답안 #338464

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
338464 2020-12-23T08:39:28 Z KoD Collapse (JOI18_collapse) C++17
35 / 100
364 ms 23628 KB
#include <bits/stdc++.h>

template <class T>
using Vec = std::vector<T>;

struct DSU {
    Vec<int> par;
    int cmp;
    std::stack<std::tuple<int, int, int, int, int>> stack;

    DSU(const int n): par(n, -1), cmp(n) { }

    int find(int x) const {
        while (par[x] >= 0) {
            x = par[x];
        }
        return x;
    }

    int merge(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) {
            return 0;
        }
        if (par[x] > par[y]) {
            std::swap(x, y);
        }
        stack.emplace(x, par[x], y, par[y], cmp);
        par[x] += par[y];
        par[y] = x;
        cmp -= 1;
        return 1;
    }

    void rollback() {
        const auto [i, x, j, y, c] = stack.top();
        stack.pop();
        par[i] = x;
        par[j] = y;
        cmp = c;
    }
};

struct Solver {
    Vec<Vec<std::pair<int, int>>> edges;

    Solver(const int t) {
        int n = 1;
        while (n < t) {
            n <<= 1;
        }
        edges.resize(2 * n);
    }

    void add(int u, int v, int l, int r) {
        l += size();
        r += size();
        while (l < r) {
            if (l & 1) {
                edges[l].emplace_back(u, v);
                l += 1;
            }
            l >>= 1;
            if (r & 1) {
                r -= 1;
                edges[r].emplace_back(u, v);
            }
            r >>= 1;
        }
    }

    void dfs(int k, DSU &uf, Vec<int> &vec) {
        int steps = 0;
        for (const auto [u, v]: edges[k]) {
            steps += uf.merge(u, v);
        }
        if (k >= size()) {
            vec[k - size()] = uf.cmp;
        }
        else {
            dfs(k * 2, uf, vec);
            dfs(k * 2 + 1, uf, vec);
        }
        while (steps--) {
            uf.rollback();
        }
    }

    Vec<int> solve(int n, int t) {
        DSU uf(n);
        Vec<int> ret(size());
        dfs(1, uf, ret);
        ret.resize(t);
        ret.shrink_to_fit();
        return ret;
    }

    int size() const {
        return edges.size() / 2;
    }
};

struct FastDSU {
    Vec<int> par;
    int cmp;

    FastDSU(const int n): par(n, -1), cmp(n) { }

    int find(int x) {
        return par[x] < 0 ? x : par[x] = find(par[x]);
    }

    void merge(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) {
            return;
        }
        if (par[x] > par[y]) {
            std::swap(x, y);
        }
        par[x] += par[y];
        par[y] = x;
        cmp -= 1;
    }
};

Vec<int> simulateCollapse(int N, Vec<int> T, Vec<int> X, Vec<int> Y, Vec<int> W, Vec<int> P) {
    const int C = T.size();
    const int Q = W.size();
    Vec<int> ret(Q);
    if (std::count(P.begin(), P.end(), P.front()) == Q) {
        Solver sol(C);
        std::map<std::pair<int, int>, int> state;
        const int bad = P.front();
        for (int i = 0; i < C; ++i) {
            const auto p = std::minmax(X[i], Y[i]);
            if (p.second <= bad || p.first > bad) {
                if (state.find(p) == state.end() || state[p] == -1) {
                    state[p] = i;
                }
                else {
                    sol.add(p.first, p.second, state[p], i);
                    state[p] = -1;
                }
            }
        }
        for (const auto &[p, v]: state) {
            if (v != -1) {
                sol.add(p.first, p.second, v, C);
            }
        } 
        const auto vec = sol.solve(N, C);
        for (int i = 0; i < Q; ++i) {
            ret[i] = vec[W[i]];
        }
    }
    else if (N <= 5000 && C <= 5000 && Q <= 5000) {
        Vec<std::pair<int, int>> edges;
        edges.reserve(C);
        for (int i = 0; i < C; ++i) {
            edges.push_back(std::minmax(X[i], Y[i]));
        }
        std::sort(edges.begin(), edges.end());
        edges.erase(std::unique(edges.begin(), edges.end()), edges.end());
        const int E = edges.size();
        Vec<int> index(C);
        for (int i = 0; i < C; ++i) {
            const std::pair<int, int> p = std::minmax(X[i], Y[i]);
            index[i] = std::lower_bound(edges.begin(), edges.end(), p) - edges.begin();
        }
        for (int i = 0; i < Q; ++i) {
            Vec<bool> use(E);
            for (int j = 0; j <= W[i]; ++j) {
                if (std::max(X[j], Y[j]) <= P[i] || std::min(X[j], Y[j]) > P[i]) {
                    use[index[j]] = !use[index[j]];
                }
            }
            FastDSU dsu(N);
            for (int j = 0; j < E; ++j) {
                if (use[j]) {
                    dsu.merge(edges[j].first, edges[j].second);
                }
            }
            ret[i] = dsu.cmp;
        }
    }
    return ret;
}

#ifdef __APPLE__
int main() {
    int N, C, Q;
    std::cin >> N >> C >> Q;
    Vec<int> T(C), X(C), Y(C);

}
#endif
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 1004 KB Output is correct
2 Correct 2 ms 364 KB Output is correct
3 Correct 3 ms 364 KB Output is correct
4 Correct 4 ms 364 KB Output is correct
5 Correct 128 ms 620 KB Output is correct
6 Correct 259 ms 748 KB Output is correct
7 Correct 14 ms 492 KB Output is correct
8 Correct 15 ms 492 KB Output is correct
9 Correct 160 ms 620 KB Output is correct
10 Correct 203 ms 748 KB Output is correct
11 Correct 364 ms 748 KB Output is correct
12 Correct 328 ms 768 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 28 ms 2432 KB Output is correct
2 Correct 29 ms 2284 KB Output is correct
3 Correct 80 ms 14828 KB Output is correct
4 Correct 28 ms 2284 KB Output is correct
5 Correct 107 ms 15724 KB Output is correct
6 Correct 36 ms 3436 KB Output is correct
7 Correct 148 ms 23628 KB Output is correct
8 Correct 124 ms 17420 KB Output is correct
9 Correct 32 ms 2668 KB Output is correct
10 Correct 34 ms 2668 KB Output is correct
11 Correct 34 ms 2924 KB Output is correct
12 Correct 141 ms 18156 KB Output is correct
13 Correct 160 ms 20704 KB Output is correct
14 Correct 161 ms 23244 KB Output is correct
15 Correct 164 ms 22348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 29 ms 2284 KB Output is correct
2 Incorrect 28 ms 2284 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 1004 KB Output is correct
2 Correct 2 ms 364 KB Output is correct
3 Correct 3 ms 364 KB Output is correct
4 Correct 4 ms 364 KB Output is correct
5 Correct 128 ms 620 KB Output is correct
6 Correct 259 ms 748 KB Output is correct
7 Correct 14 ms 492 KB Output is correct
8 Correct 15 ms 492 KB Output is correct
9 Correct 160 ms 620 KB Output is correct
10 Correct 203 ms 748 KB Output is correct
11 Correct 364 ms 748 KB Output is correct
12 Correct 328 ms 768 KB Output is correct
13 Correct 28 ms 2432 KB Output is correct
14 Correct 29 ms 2284 KB Output is correct
15 Correct 80 ms 14828 KB Output is correct
16 Correct 28 ms 2284 KB Output is correct
17 Correct 107 ms 15724 KB Output is correct
18 Correct 36 ms 3436 KB Output is correct
19 Correct 148 ms 23628 KB Output is correct
20 Correct 124 ms 17420 KB Output is correct
21 Correct 32 ms 2668 KB Output is correct
22 Correct 34 ms 2668 KB Output is correct
23 Correct 34 ms 2924 KB Output is correct
24 Correct 141 ms 18156 KB Output is correct
25 Correct 160 ms 20704 KB Output is correct
26 Correct 161 ms 23244 KB Output is correct
27 Correct 164 ms 22348 KB Output is correct
28 Correct 29 ms 2284 KB Output is correct
29 Incorrect 28 ms 2284 KB Output isn't correct
30 Halted 0 ms 0 KB -