Submission #1159942

#TimeUsernameProblemLanguageResultExecution timeMemory
1159942Der_VlaposCollapse (JOI18_collapse)C++20
35 / 100
1358 ms23612 KiB
#include "collapse.h" #include <bits/stdc++.h> using namespace std; #define pii pair<int, int> #define f first #define s second #define ll long long #define pb push_back #define all(v) v.begin(), v.end() struct DSU { struct change { int x, px, szx, y, py, szy, cnt; }; stack<change> changes; vector<int> p, sz; int cnt = 0; void init(int n) { cnt = n; p.resize(n); sz.resize(n); for (int i = 0; i < n; ++i) { sz[i] = 1; p[i] = i; } } int getR(int v) { return p[v] == v ? v : getR(p[v]); } void undo() { assert(changes.size()); auto c = changes.top(); changes.pop(); cnt = c.cnt; p[c.x] = c.px; sz[c.x] = c.szx; p[c.y] = c.py; sz[c.y] = c.szy; } void merge(int a, int b) { a = getR(a); b = getR(b); changes.push({a, p[a], sz[a], b, p[b], sz[b], cnt}); if (a == b) return; cnt--; if (sz[a] < sz[b]) swap(a, b); p[b] = a; sz[a] += sz[b]; } }; struct segTree { struct Node { vector<pii> segs; vector<int> qrs; }; vector<Node> tree; DSU dsu; int sz = 0; void init(int n) { sz = 1; while (sz < n) sz *= 2; tree.resize(2 * sz); } void addQr(int pos, int id, int v, int lv, int rv) { if (rv - lv == 1) { tree[v].qrs.pb(id); return; } int m = (lv + rv) >> 1; if (pos < m) addQr(pos, id, v * 2 + 1, lv, m); else addQr(pos, id, v * 2 + 2, m, rv); } void addQr(int pos, int id) { addQr(pos, id, 0, 0, sz); } void addSeg(int l, int r, pii e, int v, int lv, int rv) { if (l <= lv and rv <= r) { tree[v].segs.push_back(e); return; } if (rv <= l or r <= lv) return; int m = (lv + rv) >> 1; addSeg(l, r, e, v * 2 + 1, lv, m); addSeg(l, r, e, v * 2 + 2, m, rv); } void addSeg(int l, int r, pii e) { addSeg(l, r, e, 0, 0, sz); } void traverse(vector<int> &ans, int v, int lv, int rv) { for (auto e : tree[v].segs) { dsu.merge(e.f, e.s); } // cerr << v << " " << lv << " " << rv << "WAT\n"; if (rv - lv == 1) { for (auto id : tree[v].qrs) ans[id] = dsu.cnt; } int m = (lv + rv) >> 1; if (rv - lv > 1) { traverse(ans, v * 2 + 1, lv, m); traverse(ans, v * 2 + 2, m, rv); } for (int i = 0; i < tree[v].segs.size(); ++i) { auto e = tree[v].segs[i]; dsu.undo(); } } void traverse(vector<int> &ans) { traverse(ans, 0, 0, sz); } }; std::vector<int> simulateCollapse(int n, std::vector<int> t, std::vector<int> x, std::vector<int> y, std::vector<int> w, std::vector<int> p) { int q = w.size(); vector<int> ans(q); for (int i = 0; i < x.size(); ++i) if (x[i] > y[i]) swap(x[i], y[i]); int m = x.size(); if (m < 5e3 + 10 and n < 5e3 + 10 and q < 5e3 + 10) { for (int cq = 0; cq < q; ++cq) { set<pii> edges; for (int i = 0; i <= w[cq]; ++i) if (y[i] <= p[cq] or p[cq] + 1 <= x[i]) if (t[i]) edges.erase({x[i], y[i]}); else edges.insert({x[i], y[i]}); DSU dsu; dsu.init(n); for (auto [x, y] : edges) { assert(!(x <= p[cq] and p[cq] + 1 <= y)); dsu.merge(x, y); } ans[cq] = dsu.cnt; } } else { int badP = p[0]; vector<pii> qrs; for (int i = 0; i < q; ++i) qrs.pb({w[i], i}); sort(all(qrs)); vector<pair<pii, pii>> edges; int timer = 0; { int u = 0; set<pair<pii, int>> curEdges; for (int i = 0; i < m; ++i) if (y[i] <= badP or badP + 1 <= x[i]) { while (u < q and qrs[u].f < i) { qrs[u].f = timer; u++; } timer++; if (t[i] == 0) curEdges.insert({{x[i], y[i]}, timer}); else { auto it = curEdges.lower_bound({{x[i], y[i]}, -1}); edges.pb({{x[i], y[i]}, {it->s, timer}}); curEdges.erase(it); } } for (; u < q; ++u) qrs[u].f = timer; timer++; for (auto [e, st] : curEdges) edges.pb({e, {st, timer}}); } segTree tree; tree.init(timer); tree.dsu.init(n); for (auto [t, id] : qrs) tree.addQr(t, id); for (auto [e, t] : edges) tree.addSeg(t.f, t.s, e); tree.traverse(ans); } return ans; } // #include "collapse.h" // #include <cstdio> // #include <cstdlib> // int main(int argc, char *argv[]) // { // int N, C, Q; // scanf("%d%d%d", &N, &C, &Q); // std::vector<int> T(C), X(C), Y(C); // for (int i = 0; i < C; i++) // { // scanf("%d%d%d", &T[i], &X[i], &Y[i]); // } // std::vector<int> W(Q), P(Q); // for (int i = 0; i < Q; i++) // { // scanf("%d%d", &W[i], &P[i]); // } // auto res = simulateCollapse(N, T, X, Y, W, P); // for (auto i : res) // { // printf("%d\n", i); // } // }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...