Submission #553273

#TimeUsernameProblemLanguageResultExecution timeMemory
553273RaresFelixCollapse (JOI18_collapse)C++17
0 / 100
34 ms3604 KiB
#include "collapse.h" #include <bits/stdc++.h> using namespace std; using Edge = tuple<int, int, int, int>; //from, to, begin, end using vEd = vector<Edge>; using vi = vector<int>; struct DSU { /// with roll_back int n; vector<int> P, S; DSU(int n) : n(n) { P.resize(n), S.assign(n, 1); for(int i = 0; i < n; ++i) P[i] = i; } int repr(int u) { return u == P[u] ? u : repr(P[u]); } int nr_uni = 0; stack<int> RP, RS; void uni(int u, int v) { u = repr(u), v = repr(v); if(u == v) return; if(S[u] < S[v]) swap(u, v); ++nr_uni, RP.push(v); RS.push(S[v]); P[v] = u, S[u] += S[v]; } void roll_back(int update_count) { while(nr_uni > update_count) { --nr_uni; P[RP.top()] = RP.top(); S[RP.top()] = RS.top(); RP.pop(), RS.pop(); } } }; struct Bucket { DSU Simu; int begin, end; Bucket(int n, int begin, int end) : Simu(n), begin(begin), end(end) {} vector<Edge> idk; void add_edge(Edge nou) { auto &[f, t, b, e] = nou; if(e < begin || end < b) return; if(b <= begin && end <= e) { //complet Simu.uni(f, t); return; } idk.push_back(nou); } int query(int timp) { int count0 = Simu.nr_uni; for(auto &it : idk) { auto &[f, t, b, e] = it; if(b <= timp && timp <= e) Simu.uni(f, t); } int re = Simu.nr_uni; Simu.roll_back(count0); return re; } }; void solve(int n, int c, int q, vEd &edges, vi &W, vi &P, vi &R) { R.assign(q, 0); vector<vi> Queries(c + 1); for(int i = 0; i < q; ++i) Queries[P[i]].push_back(i); vector<vEd> Add(n + 1); for(auto &[f, t, b, e] : edges) Add[t].push_back({f, t, b, e}); int bucketSize = int(sqrt(c + 1)); vector<Bucket> Sol; for(int lp = 0; lp <= c + 1; lp += bucketSize) Sol.emplace_back(n, lp, lp + bucketSize - 1); for(int i = 0; i < n; ++i) { for(auto &it : Add[i]) for(auto &seg : Sol) seg.add_edge(it); for(auto &qid : Queries[i]) { int w = W[qid]; int re = 0; for(auto &seg : Sol) { if(seg.begin <= w && w <= seg.end) { re = seg.query(w); break; } } R[qid] = i + 1 - re; } } } vector<int> simulateCollapse( int n, vector<int> T, vector<int> X, vector<int> Y, vector<int> W, vector<int> P ) { vEd edges; int c = T.size(), q = W.size(); map<pair<int, int>, int> enabled; for(int i = 0 ; i < c; ++i) if(X[i] > Y[i]) swap(X[i], Y[i]); for(int i = 0 ; i < c; ++i) { if(!T[i]) enabled[{X[i], Y[i]}] = i; else { edges.push_back({X[i], Y[i], enabled[{X[i], Y[i]}], c}); enabled[{X[i], Y[i]}] = -1; } } for(auto [p, e] : enabled) if(e != -1) { auto [f, t] = p; edges.push_back({f, t, e, c + 1}); } vector<int> R, R1, R2; solve(n, c, q, edges, W, P, R1); for(auto &it : P) it = n - 1 - it; for(auto &[a, b, c, d] : edges) a = n - 1 - a, b = n - 1 - b, a ^= b, b ^= a, a ^= b; solve(n, c, q, edges, W, P, R2); for(int i = 0; i < q; ++i) R.push_back(R1[i] + R2[i]); return R; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...