답안 #691863

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
691863 2023-01-31T19:00:56 Z piOOE Prize (CEOI22_prize) C++17
10 / 100
2228 ms 335112 KB
#include <bits/stdc++.h>

using namespace std;

#define int int64_t

void massert(bool v) {
    if (!v) {
        auto start = clock();
        int x = 1;
        while ((clock() - start) < 5 * CLOCKS_PER_SEC) {
            x <<= 1;
            x += 1;
        }
    }
}

struct HLD {
    vector<int> par, siz, head, tin, tout, ord, depth;

    int dfs1(int i, vector<vector<int>> &g) {
        for (int &t: g[i]) {
            if (t != par[i]) {
                depth[t] = depth[i] + 1;
                par[t] = i;
                siz[i] += dfs1(t, g);
                if (siz[t] > siz[g[i][0]] || g[i][0] == par[i]) swap(t, g[i][0]);
            }
        }
        return siz[i];
    }

    void dfs2(int i, int &T, const vector<vector<int>> &g) {
        tin[i] = T++;
        for (int t: g[i]) {
            if (t != par[i]) {
                head[t] = (T == tin[i] + 1 ? head[i] : t);
                dfs2(t, T, g);
            }
        }
        tout[i] = T;
    }

    HLD() = default;

    HLD(vector<vector<int>> g, int r = 0)
            : par(g.size(), -1), siz(g.size(), 1), head(g.size(), r), tin(g.size()), ord(g.size()), tout(g.size()),
              depth(g.size()) {
        dfs1(r, g);
        int x = 0;
        dfs2(r, x, g);
        for (int i = 0; i < g.size(); ++i) ord[tin[i]] = i;
    }

    vector<pair<int, int>> path(int a, int b) {
        vector<pair<int, int>> res;
        for (;; b = par[head[b]]) {
            if (tin[b] < tin[a]) swap(a, b);
            if (tin[head[b]] <= tin[a]) {
                res.emplace_back(tin[a], tin[b] + 1);
                return res;
            }
            res.emplace_back(tin[head[b]], tin[b] + 1);
        }
    }

    pair<int, int> subtree(int i) {
        return {tin[i], tin[i] + siz[i]};
    }

    int dist(int a, int b) {
        return depth[a] + depth[b] - 2 * depth[lca(a, b)];
    }

    int lca(int a, int b) {
        for (;; b = par[head[b]]) {
            if (tin[b] < tin[a]) swap(a, b);
            if (tin[head[b]] <= tin[a]) return a;
        }
    }

    bool isp(int a, int b) {
        return tin[a] <= tin[b] && tout[a] >= tout[b];
    }
} t1, t2;

vector<int> normalize(int n, int root, vector<vector<pair<int, int>>> g) {
    vector<int> dist(n, -1);
    dist[root] = 0;
    vector<bool> used(n);

    function<void(int)> dfs = [&](int v) {
        used[v] = true;
        for (auto [to, w]: g.at(v)) {
            if (!used[to]) {
                dist[to] = dist[v] + w;
                dfs(to);
            }
        }
    };

    dfs(root);

    return dist;
}

int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, k, q, t;
    cin >> n >> k >> q >> t;

    vector<int> p1(n), p2(n);

    int root1 = -1, root2 = -1;
    for (int i = 0; i < n; ++i) {
        cin >> p1[i];
        if (p1[i] == -1) {
            root1 = i;
        } else {
            p1[i] -= 1;
        }
    }

    for (int i = 0; i < n; ++i) {
        cin >> p2[i];
        if (p2[i] == -1) {
            root2 = i;
        } else {
            p2[i] -= 1;
        }
    }

    massert(max(root1, root2) < n && min(root1, root2) >= 0);

    vector<vector<int>> adj(n);

    for (int i = 0; i < n; ++i) {
        if (p1[i] != -1) {
            adj[p1[i]].push_back(i);
        }
    }

    t1 = HLD(adj, root1);

    for (int i = 0; i < n; ++i) {
        adj[i].clear();
    }

    for (int i = 0; i < n; ++i) {
        if (p2[i] != -1) {
            adj[p2[i]].push_back(i);
        }
    }

    t2 = HLD(adj, root2);

    vector<pair<int, int>> questions;

    vector<bool> in(n);
    in[root1] = in[root2] = true;

    vector<int> ord;
    ord.push_back(root1);
    if (root2 != root1) ord.push_back(root2);
    int cnt = 1 + (root1 != root2);
    for (int i = 0; i < n && cnt < k; ++i) {
        if (!in[i]) {
            ord.push_back(i);
            ++cnt;
        }
    }

    for (int x : ord) {
        cout << x + 1 << " ";
    }
    cout << endl;

    sort(ord.begin(), ord.end(), [&](int i, int j) {
        return t2.tin[i] < t2.tin[j];
    });

    for (int i = 1; i < ord.size(); ++i) {
        questions.emplace_back(ord[i - 1], ord[i]);
    }

    assert(questions.size() <= q);
    for (auto [x, y]: questions) {
        cout << "? " << x + 1 << " " << y + 1 << '\n';
    }
    cout << "!" << endl;

    vector<vector<pair<int, int>>> g1(n), g2(n);

    int h1 = root1, h2 = root2;

    vector<int> aa, bb;
    auto addEdge = [&](int tt, int x, int y, int w) {
        if (x == y) {
            return;
        }
        if (tt == 0) aa.push_back(x), aa.push_back(y);
        else bb.push_back(x), bb.push_back(y);
        massert(x < n && y < n && x >= 0 && y >= 0);
        (tt == 0 ? g1[x] : g2[x]).emplace_back(y, w);
        (tt == 0 ? g1[y] : g2[y]).emplace_back(x, -w);
    };

    for (auto [x, y]: questions) {
        int a, b, c, d;
        cin >> a >> b >> c >> d;

        int c1 = t1.lca(x, y);
        int c2 = t2.lca(x, y);

//        if (t1.isp(c1, h1)) {
//            h1 = c1;
//        }
//        if (t2.isp(c2, h2)) {
//            h2 = c2;
//        }

        addEdge(0, c1, x, a);
        addEdge(0, c1, y, b);
        addEdge(1, c2, x, c);
        addEdge(1, c2, y, d);
    }

    auto first = normalize(n, h1, g1);
    auto second = normalize(n, h2, g2);

    vector<pair<int, int>> queries(t);
    for (auto &[a, b]: queries) {
        cin >> a >> b;
        a -= 1, b -= 1;
    }

    for (int i : aa) {
        assert(first[i] != -1);
    }
    for (int i : bb) {
        assert(second[i] != -1);
    }

    for (auto [a, b] : queries) {
        int dist1 = first[a] - 2 * first[t1.lca(a, b)] + first[b];
        int dist2 = second[a] - 2 * second[t2.lca(a, b)] + second[b];

        cout << dist1 << " " << dist2 << '\n';
    }

    return 0;
}

Compilation message

Main.cpp: In constructor 'HLD::HLD(std::vector<std::vector<long int> >, int64_t)':
Main.cpp:19:44: warning: 'HLD::ord' will be initialized after [-Wreorder]
   19 |     vector<int> par, siz, head, tin, tout, ord, depth;
      |                                            ^~~
Main.cpp:19:38: warning:   'std::vector<long int> HLD::tout' [-Wreorder]
   19 |     vector<int> par, siz, head, tin, tout, ord, depth;
      |                                      ^~~~
Main.cpp:46:5: warning:   when initialized here [-Wreorder]
   46 |     HLD(vector<vector<int>> g, int r = 0)
      |     ^~~
Main.cpp:52:27: warning: comparison of integer expressions of different signedness: 'int64_t' {aka 'long int'} and 'std::vector<std::vector<long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   52 |         for (int i = 0; i < g.size(); ++i) ord[tin[i]] = i;
      |                         ~~^~~~~~~~~~
Main.cpp: In function 'int32_t main()':
Main.cpp:184:23: warning: comparison of integer expressions of different signedness: 'int64_t' {aka 'long int'} and 'std::vector<long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  184 |     for (int i = 1; i < ord.size(); ++i) {
      |                     ~~^~~~~~~~~~~~
In file included from /usr/include/c++/10/cassert:44,
                 from /usr/include/x86_64-linux-gnu/c++/10/bits/stdc++.h:33,
                 from Main.cpp:1:
Main.cpp:188:29: warning: comparison of integer expressions of different signedness: 'std::vector<std::pair<long int, long int> >::size_type' {aka 'long unsigned int'} and 'int64_t' {aka 'long int'} [-Wsign-compare]
  188 |     assert(questions.size() <= q);
      |            ~~~~~~~~~~~~~~~~~^~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 1072 ms 168820 KB Output is correct
2 Correct 1097 ms 176188 KB Output is correct
3 Correct 965 ms 150832 KB Output is correct
4 Correct 911 ms 148112 KB Output is correct
5 Correct 1033 ms 156032 KB Output is correct
6 Correct 1025 ms 156816 KB Output is correct
7 Correct 1069 ms 156728 KB Output is correct
8 Correct 1036 ms 155096 KB Output is correct
9 Correct 955 ms 150604 KB Output is correct
10 Correct 1018 ms 154744 KB Output is correct
11 Correct 944 ms 145252 KB Output is correct
12 Correct 977 ms 153396 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1150 ms 175776 KB Output is correct
2 Correct 1040 ms 167712 KB Output is correct
3 Runtime error 825 ms 157764 KB Execution killed with signal 13
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 938 ms 163812 KB Output is correct
2 Correct 995 ms 163876 KB Output is correct
3 Runtime error 634 ms 140916 KB Execution killed with signal 13
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2056 ms 327212 KB Output is correct
2 Correct 2069 ms 327228 KB Output is correct
3 Runtime error 1357 ms 281888 KB Execution killed with signal 13
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2211 ms 335044 KB Output is correct
2 Correct 2228 ms 335112 KB Output is correct
3 Runtime error 1542 ms 286916 KB Execution killed with signal 13
4 Halted 0 ms 0 KB -