Submission #129656

#TimeUsernameProblemLanguageResultExecution timeMemory
129656qkxwsmCollapse (JOI18_collapse)C++14
0 / 100
191 ms33132 KiB
#include <bits/stdc++.h> #include "collapse.h" using namespace std; template<class T, class U> void ckmin(T &a, U b) { if (a > b) a = b; } template<class T, class U> void ckmax(T &a, U b) { if (a < b) a = b; } #define MP make_pair #define PB push_back #define LB lower_bound #define UB upper_bound #define fi first #define se second #define FOR(i, a, b) for (auto i = (a); i < (b); i++) #define FORD(i, a, b) for (auto i = (a) - 1; i >= (b); i--) #define SZ(x) ((int) (x).size()) #define ALL(x) (x).begin(), (x).end() #define INF 1000000007 #define LLINF 2696969696969696969 #define MAXN 400013 #define MAGIC 521 typedef long long ll; typedef long double ld; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef vector<int> vi; typedef vector<ll> vl; typedef vector<pii> vpi; typedef vector<pll> vpl; int N, Q; vi ans; vector<array<int, 4> > events; int die[MAXN]; vi ord, cand; vi ch[MAXN]; map<int, int> rec[MAXN]; struct dsu { int dsu[MAXN], siz[MAXN]; vi edits; void init() { FOR(i, 0, N) { dsu[i] = i; siz[i] = 1; } } void rollback() { for (int x : edits) { dsu[x] = x; siz[x] = 1; } edits.clear(); } int get(int u) { if (u == dsu[u]) return u; int v = get(dsu[u]); edits.PB(u); dsu[u] = v; return v; } bool merge(int u, int v) { u = get(u); v = get(v); if (u == v) return false; if (siz[u] > siz[v]) swap(u, v); siz[v] += siz[u]; dsu[u] = v; return true; } }; dsu D[2]; bool cmp(int a, int b) { return events[a][2] < events[b][2]; } void proc(int l, int r) { //build the set of edges now! D[0].init(); D[1].init(); cand.clear(); ord.clear(); FOR(i, 0, N) { ch[i].clear(); } FOR(i, l, r + 1) { if (events[i][1] == 2) { ord.PB(i); } } sort(ALL(ord), cmp); FOR(i, 0, l) { if (events[i][1] != 0) continue; int u = events[i][2], v = events[i][3]; if (die[i] <= r) cand.PB(i); else { ch[v].PB(u); } } int cc = 0, cp = 0; for (int p : ord) { int u = events[p][2], qid = events[p][3], t = events[p][0]; while(cp <= u) { cc++; for (int v : ch[cp]) { if (D[0].merge(cp, v)) cc--; } cp++; } int res = cc; for (int x : cand) { int v = events[x][2], w = events[x][3]; if (die[x] > t && w <= u) { v = D[0].get(v); w = D[0].get(w); if (D[1].merge(v, w)) res--; } } FOR(j, l, p) { if (events[j][1] != 0) continue; int v = events[j][2], w = events[j][3]; if (die[j] > t && w <= u) { v = D[0].get(v); w = D[0].get(w); if (D[1].merge(v, w)) res--; } } D[1].rollback(); ans[qid] += res; } return; } void solve() { FOR(i, 0, N) rec[i].clear(); FOR(i, 0, SZ(events)) { if (events[i][1] == 2) continue; if (events[i][1] == 0) { rec[events[i][2]][events[i][3]] = i; die[i] = SZ(events); } else { die[rec[events[i][2]][events[i][3]]] = i; } } for (int i = 0; i < SZ(events); i += MAGIC) { proc(i, min(i + MAGIC, SZ(events)) - 1); } } vi simulateCollapse(int n, vi t, vi x, vi y, vi w, vi p) { N = n; Q = SZ(w); ans.resize(Q); FOR(i, 0, SZ(t)) { if (x[i] > y[i]) swap(x[i], y[i]); events.PB({i, t[i], x[i], y[i]}); } FOR(i, 0, Q) { events.PB({w[i], 2, p[i], i}); } sort(ALL(events)); FOR(i, 0, SZ(events)) { events[i][0] = i; } //hm ok each edge has a birth and death time. solve(); for (auto &e : events) { if (e[1] == 2) { e[2] = N - 2 - e[2]; } else { e[2] = N - 1 - e[2]; e[3] = N - 1 - e[3]; swap(e[2], e[3]); } } solve(); return ans; //event: disconnect u -> v, connect u -> v, ask qid x pos y: so you store time, typ, who it happens to }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...