Submission #1131460

#TimeUsernameProblemLanguageResultExecution timeMemory
1131460vladiliusCollapse (JOI18_collapse)C++20
0 / 100
11353 ms558684 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; using pii = pair<int, int>; #define pb push_back #define ff first #define ss second const int N = 5e5; const int K = 205; struct dsu{ vector<int> sz, p; vector<pair<int&, int>> hist; vector<int> sizes; int n, cc, cc1; void init(int ns){ n = ns; sz.resize(n + 1); p.resize(n + 1); for (int i = 1; i <= n; i++){ sz[i] = 1; p[i] = i; } cc = n; cc1 = 0; } int get(int v){ return (v == p[v]) ? v : get(p[v]); } void unite(int x, int y){ x = get(x); y = get(y); if (x == y) return; if (sz[x] > sz[y]) swap(x, y); hist.pb({p[x], p[x]}); p[x] = y; hist.pb({sz[y], sz[y]}); sz[y] += sz[x]; hist.pb({cc, cc}); hist.pb({cc1, cc1}); cc--; cc1++; } void check_point(){ sizes.pb((int) hist.size()); } void roll_back(){ while (hist.size() != sizes.back()){ hist.back().ff = hist.back().ss; hist.pop_back(); } sizes.pop_back(); } }; vector<pii> ed[N], qs[N], d1[N], d2[N], f; vector<int> out, mv; int k; dsu T[K], F; void add(int v, int tl, int tr, int& l, int& r, pii x){ if (l > tr || r < tl) return; if (l <= tl && tr <= r){ ed[v].pb(x); return; } int tm = (tl + tr) / 2, vv = 2 * v; add(vv, tl, tm, l, r, x); add(vv + 1, tm + 1, tr, l, r, x); } void solve(int v, int tl, int tr){ int s1 = (int) d1[v].size(), s2 = (int) d2[v].size(); for (int j = 0; j < k; j++) T[j].check_point(); for (auto [x, y]: ed[v]){ int V = max(x, y); for (int j = 0; j < k; j++){ auto [l, r] = f[j]; if (V <= l){ T[j].unite(x, y); } } d1[V].pb({x, y}); V = min(x, y) - 1; for (int j = 0; j < k; j++){ auto [l, r] = f[j]; if (r <= V){ T[j].unite(x, y); } } d2[V].pb({x, y}); } if (tl == tr){ for (auto [v, ii]: qs[tl]){ for (int j = 0; j < k; j++){ auto [l, r] = f[j]; if (l <= v && v <= r){ F.check_point(); for (int s = l; s <= v; s++){ s = mv[s]; if (s > v) break; for (auto [u1, u2]: d1[s]){ int v1 = T[j].get(u1); int v2 = T[j].get(u2); F.unite(v1, v2); } } for (int s = v; s <= r; s++){ s = mv[s]; if (s > r) break; for (auto [u1, u2]: d2[s]){ int v1 = T[j].get(u1); int v2 = T[j].get(u2); F.unite(v1, v2); } } out[ii] = (T[j].cc - F.cc1); F.roll_back(); break; } } } } else { int tm = (tl + tr) / 2, vv = 2 * v; solve(vv, tl, tm); solve(vv + 1, tm + 1, tr); } for (int j = 0; j < k; j++){ T[j].roll_back(); } while (d1[v].size() != s1) d1[v].pop_back(); while (d2[v].size() != s2) d2[v].pop_back(); } vector<int> simulateCollapse(int n, vector<int> t, vector<int> x, vector<int> y, vector<int> w, vector<int> p){ int m = (int) t.size(); x.insert(x.begin(), 0); y.insert(y.begin(), 0); t.insert(t.begin(), 0); for (int i = 1; i <= m; i++){ x[i]++; y[i]++; } int q = (int) w.size(); for (int i = 0; i < q; i++){ p[i]++; w[i]++; } const int S = min(m, 1200); out.resize(q); vector<int> c1(n + 1); for (int i = 1; i <= m; i++){ c1[max(x[i], y[i])]++; c1[min(x[i], y[i]) - 1]++; } int i = 1; while (i <= n){ if (c1[i] >= S){ f.pb({i, i}); i++; continue; } int j = i, sum = 0; while (j <= n && sum < S){ if (c1[j] >= S){ j--; break; } sum += c1[j]; j++; } f.pb({i, min(n, j)}); i = j + 1; } k = (int) f.size(); for (int i = 0; i < k; i++) T[i].init(n); mv.resize(n + 2); mv[n + 1] = n + 1; for (int i = n; i > 0; i--){ if (c1[i]) mv[i] = i; else mv[i] = mv[i + 1]; } map<pii, int> mp; F.init(n); for (int i = 1; i <= m; i++){ if (x[i] > y[i]) swap(x[i], y[i]); if (!t[i]){ if (mp.find({x[i], y[i]}) == mp.end()){ mp[{x[i], y[i]}] = i; } } else { add(1, 1, m, mp[{x[i], y[i]}], i, {x[i], y[i]}); mp.erase({x[i], y[i]}); } } for (auto tt: mp){ add(1, 1, m, tt.ss, m, tt.ff); } for (int i = 0; i < q; i++) qs[w[i]].pb({p[i], i}); solve(1, 1, m); return out; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...