Submission #1254686

#TimeUsernameProblemLanguageResultExecution timeMemory
1254686minhpkCollapse (JOI18_collapse)C++20
0 / 100
16 ms4484 KiB
#include "collapse.h" #include <bits/stdc++.h> using namespace std; static const int MAXN = 100000; typedef pair<int,int> pii; int a, b, c; vector<int> t, z, z1, w, w1; vector<int> res; struct Interval { int u, v, l, r; }; vector<Interval> intervals; vector<vector<pii>> pos; vector<vector<pii>> seg_pref, seg_suf; struct ST { int n; vector<int> f, lazy; void init(int _n) { n = _n; f.assign(4*n+4, 0); lazy.assign(4*n+4, 0); } void apply(int id, int l, int r, int v) { f[id] += v; lazy[id] += v; } void push(int id) { if (!lazy[id]) return; apply(id*2, 0, 0, lazy[id]); apply(id*2+1, 0, 0, lazy[id]); lazy[id] = 0; } void update(int id, int l, int r, int L, int R, int v) { if (R < l || r < L) return; if (L <= l && r <= R) { apply(id, l, r, v); return; } int mid = (l+r)>>1; push(id); update(id*2, l, mid, L, R, v); update(id*2+1, mid+1, r, L, R, v); f[id] = f[id*2] + f[id*2+1]; } int get(int id, int l, int r, int p) { if (l == r) return f[id]; int mid = (l+r)>>1; push(id); return p <= mid ? get(id*2, l, mid, p) : get(id*2+1, mid+1, r, p); } }; ST stree; void add_interval(vector<vector<pii>>& seg, int id, int l, int r, int L, int R, pii e) { if (R < l || r < L) return; if (L <= l && r <= R) { seg[id].push_back(e); return; } int mid = (l+r)>>1; add_interval(seg, id*2, l, mid, L, R, e); add_interval(seg, id*2+1, mid+1, r, L, R, e); } int par[MAXN+5], sz[MAXN+5]; struct Roll { int y, sy, id, type, w; }; vector<Roll> roll_stack; int findp(int u) { return par[u]==u ? u : findp(par[u]); } bool join(int u, int v, int id, int type) { int x = findp(u), y = findp(v); if (x == y) return false; if (sz[x] < sz[y]) swap(x,y); roll_stack.push_back({y, sz[y], id, type, (type==1? max(u,v): min(u,v))}); par[y] = x; sz[x] += sz[y]; return true; } void rollback(int id) { while (!roll_stack.empty() && roll_stack.back().id == id) { auto R = roll_stack.back(); roll_stack.pop_back(); int y = R.y, sy = R.sy; int type = R.type, w = R.w; int x = par[y]; sz[x] -= sy; par[y] = y; // undo segment-tree update if (type == 1) { stree.update(1, 0, a-1, w, a-1, +1); } else { stree.update(1, 0, a-1, 0, w, +1); } } } void dfs_pref(int id, int l, int r) { sort(seg_pref[id].begin(), seg_pref[id].end(), [](pii A, pii B){ return max(A.first,A.second) < max(B.first,B.second); }); for (auto &e : seg_pref[id]) { if (join(e.first, e.second, id, 1)) { int wv = max(e.first, e.second); stree.update(1, 0, a-1, wv, a-1, -1); } } if (l == r) { for (auto &pr : pos[l]) res[pr.second] = stree.get(1,0,a-1,pr.first); } else { int m=(l+r)>>1; dfs_pref(id*2, l, m); dfs_pref(id*2+1, m+1, r); } rollback(id); } void dfs_suf(int id, int l, int r) { sort(seg_suf[id].begin(), seg_suf[id].end(), [](pii A, pii B){ return min(A.first,A.second) > min(B.first,B.second); }); for (auto &e : seg_suf[id]) { if (join(e.first, e.second, id, 2)) { int wv = min(e.first, e.second); stree.update(1, 0, a-1, 0, wv, -1); } } if (l == r) { for (auto &pr : pos[l]) res[pr.second] += stree.get(1,0,a-1,pr.first); } else { int m=(l+r)>>1; dfs_suf(id*2, l, m); dfs_suf(id*2+1, m+1, r); } rollback(id); } vector<int> simulateCollapse(int N, vector<int> T_, vector<int> X_, vector<int> Y_, vector<int> W_, vector<int> P_) { a=N; b=T_.size(); c=W_.size(); t=T_; z=X_; z1=Y_; w=W_; w1=P_; res.assign(c,0); pos.assign(b,{}); seg_pref.assign(4*b+4,{}); seg_suf.assign(4*b+4,{}); map<pii,int> last; for (int i=0;i<b;i++) { pii e={z[i],z1[i]}; if (t[i]==0) last[e]=i; else { intervals.push_back({e.first,e.second,last[e],i-1}); last.erase(e); } } for (auto &p:last) intervals.push_back({p.first.first,p.first.second,p.second,b-1}); for (auto &I: intervals) { add_interval(seg_pref,1,0,b-1,I.l,I.r,{I.u,I.v}); add_interval(seg_suf,1,0,b-1,I.l,I.r,{I.u,I.v}); } for (int i=0;i<c;i++) pos[w1[i]].push_back({w[i],i}); stree.init(a); for (int x=0;x<a;x++) stree.update(1,0,a-1,x,a-1,1); iota(par,par+a,0); fill(sz,sz+a,1); dfs_pref(1,0,b-1); stree.init(a); for (int x=0;x<a;x++) stree.update(1,0,a-1,0,x,1); iota(par,par+a,0); fill(sz,sz+a,1); dfs_suf(1,0,b-1); return res; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...