Submission #547800

#TimeUsernameProblemLanguageResultExecution timeMemory
547800blueCollapse (JOI18_collapse)C++17
5 / 100
15079 ms5304 KiB
#include "collapse.h" #include <vector> #include <algorithm> #include <set> #include <queue> #include <iostream> using namespace std; using vi = vector<int>; using vvi = vector<vi>; using pii = pair<int, int>; #define sz(x) int(x.size()) const int bs = 1; struct dss { int Z; vi parent; vi subtree; dss() { ; } dss(int Z_) { Z = Z_; parent = subtree = vi(Z); for(int i = 0; i < Z; i++) { parent[i] = i; subtree[i] = 1; } } int root(int u) { if(parent[u] == u) return u; else return (parent[u] = root(parent[u])); } bool join(int u, int v) { u = root(u); v = root(v); if(u == v) return 0; if(subtree[u] < subtree[v]) swap(u, v); parent[v] = u; subtree[u] += subtree[v]; return 1; } bool connected(int u, int v) { return root(u) == root(v); } }; vi simulateCollapse(int N, vi T, vi X, vi Y, vi W, vi P) { int C = sz(X); int Q = sz(W); for(int i = 0; i < C; i++) { if(X[i] > Y[i]) swap(X[i], Y[i]); } vi queries[N]; for(int q = 0; q < Q; q++) queries[P[q]].push_back(q); vi res(Q); for(int bl = 0; bl*bs < C; bl++) { int l = bl*bs, r = min((bl+1)*bs - 1, C-1); // cerr << "l r = " << l << ' ' << r << '\n'; set<pii> critical; for(int i = l; i <= r; i++) { critical.insert({X[i], Y[i]}); } set<pii> edgeset; for(int i = 0; i < l; i++) { if(critical.find({X[i], Y[i]}) != critical.end()) continue; if(T[i] == 0) edgeset.insert({X[i], Y[i]}); else edgeset.erase({X[i], Y[i]}); } vi fwdedge[N], backedge[N]; for(auto e : edgeset) { fwdedge[e.first].push_back(e.second); backedge[e.second].push_back(e.first); } dss dsu1(N); int comps = 0; vi checkedge[N]; vi vis(N, 0); for(int i = 0; i <= N-2; i++) { comps++; for(int j : backedge[i]) { comps -= dsu1.join(i, j); } for(int q : queries[i]) { int t = W[q]; if(!(l <= t && t <= r)) continue; set<pii> currcritical; vi vertlist; for(int ei = l; ei <= r; ei++) { if(Y[ei] >= P[q] + 1) continue; if(ei > W[q]) continue; if(T[ei] == 0) currcritical.insert({X[ei], Y[ei]}); else currcritical.erase({X[ei], Y[ei]}); } for(auto k : currcritical) { int rx = dsu1.root(k.first); int ry = dsu1.root(k.second); checkedge[rx].push_back(ry); checkedge[ry].push_back(rx); vertlist.push_back(rx); vertlist.push_back(ry); } int thiscomps = comps; for(int z : vertlist) { if(vis[z]) continue; queue<int> tbv; tbv.push(z); vis[z] = 1; while(!tbv.empty()) { int u = tbv.front(); tbv.pop(); for(int v : checkedge[u]) { if(vis[v]) continue; vis[v] = 1; thiscomps--; tbv.push(v); } } } for(int v : vertlist) { vis[v] = 0; checkedge[v].clear(); } res[q] += thiscomps; // cerr << "thiscomps = " << thiscomps << '\n'; } } dss dsu2(N); comps = 0; for(int i = 0; i < N; i++) checkedge[i].clear(); vis = vi(N, 0); for(int i = N-1; i >= 1; i--) { comps++; for(int j : fwdedge[i]) { comps -= dsu2.join(i, j); } for(int q : queries[i-1]) { int t = W[q]; if(!(l <= t && t <= r)) continue; set<pii> currcritical; vi vertlist; for(int ei = l; ei <= r; ei++) { if(X[ei] <= P[q]) continue; if(ei > W[q]) continue; if(T[ei] == 0) currcritical.insert({X[ei], Y[ei]}); else currcritical.erase({X[ei], Y[ei]}); } for(auto k : currcritical) { int rx = dsu2.root(k.first); int ry = dsu2.root(k.second); checkedge[rx].push_back(ry); checkedge[ry].push_back(rx); vertlist.push_back(rx); vertlist.push_back(ry); } int thiscomps = comps; for(int z : vertlist) { if(vis[z]) continue; queue<int> tbv; tbv.push(z); vis[z] = 1; while(!tbv.empty()) { int u = tbv.front(); tbv.pop(); for(int v : checkedge[u]) { if(vis[v]) continue; vis[v] = 1; thiscomps--; tbv.push(v); } } } for(int v : vertlist) { vis[v] = 0; checkedge[v].clear(); } res[q] += thiscomps; // cerr << "thiscomps = " << thiscomps << '\n'; } } } 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...