Submission #1040697

#TimeUsernameProblemLanguageResultExecution timeMemory
1040697PlurmInside information (BOI21_servers)C++11
100 / 100
3412 ms232788 KiB
#include <bits/stdc++.h> using namespace std; vector<int> g[1 << 19]; vector<int> rg[1 << 19]; int st[1 << 19]; int dep[1 << 19]; int ddep[1 << 19]; int t; int ett[1048576]; int rev[1048576]; void dfs(int u, int p = 0, int d = 0){ t++; ddep[u] = d; ett[t] = dep[u] = dep[p]+1; st[u] = t; rev[t] = u; for(int v : g[u]){ if(v == p) continue; dfs(v, u, d+1); t++; ett[t] = dep[u]; rev[t] = u; } for(int v : rg[u]){ if(v == p) continue; dfs(v, u, d-1); t++; ett[t] = dep[u]; rev[t] = u; } } pair<int, int> sparse[21][1048576]; void build(){ for(int i = 0; i < 1048576; i++) sparse[0][i] = {ett[i], rev[i]}; for(int i = 1; i < 21; i++){ for(int j = 0; j + (1 << i) < 1048576; j++){ sparse[i][j] = min(sparse[i-1][j], sparse[i-1][j+(1<<(i-1))]); } } } inline bool search(const int& a, const int& d){ int l, r; tie(l, r) = minmax(st[a], st[d]); int lg = 31 - __builtin_clz(r-l+1); return dep[a] + dep[d] - 2*dep[min(sparse[lg][l], sparse[lg][r-(1<<lg)+1]).second] == ddep[d] - ddep[a]; } tuple<int,int,int> buffer[1 << 19]; int bsz; const int THRESH = 1024; int qs[1 << 19]; int evp[1 << 19]; int update(int u, int p = 0, int d = 0){ for(int v : rg[u]){ if(v == p) continue; d += update(v, u, 0); } d += evp[u]; qs[u] += d; for(int v : g[u]){ if(v == p) continue; update(v, u, d); } return d; } int count(int d){ if(bsz > THRESH){ for(int i = 0; i < bsz; i++){ evp[get<0>(buffer[i])]--; evp[get<1>(buffer[i])]--; evp[get<2>(buffer[i])] += 2; } update(1); for(int i = 0; i < bsz; i++){ evp[get<0>(buffer[i])]++; evp[get<1>(buffer[i])]++; evp[get<2>(buffer[i])] -= 2; } bsz = 0; } int ret = qs[d]; for(int i = 0; i < bsz; i++){ if(search(get<0>(buffer[i]), d) || search(get<1>(buffer[i]), d)){ ret++; }else if(search(get<2>(buffer[i]), d)){ ret += 2; } } return ret; } int main(){ ios::sync_with_stdio(false); cin.tie(0); int n, k; cin >> n >> k; k += n-1; vector<tuple<int,int,int>> cmds; vector<int> ids(n+1); for(int i = 1; i <= n; i++){ ids[i] = i; } int last = n; for(int i = 0; i < k; i++){ string cmd; cin >> cmd; int a, b, d; switch(cmd[0]){ case 'S': cin >> a >> b; last++; g[last].push_back(ids[a]); rg[ids[a]].push_back(last); g[last].push_back(ids[b]); rg[ids[b]].push_back(last); ids[a] = ids[b] = last; cmds.push_back({0, a, b}); break; case 'Q': cin >> a >> d; cmds.push_back({1, a, d}); break; case 'C': cin >> d; cmds.push_back({2, d, 0}); break; } } dfs(1); build(); for(int i = 1; i <= n; i++){ ids[i] = i; qs[i]++; } last = n; for(int i = 0; i < k; i++){ int a, b, d; switch(get<0>(cmds[i])){ case 0: a = get<1>(cmds[i]); b = get<2>(cmds[i]); last++; buffer[bsz++] = {ids[a], ids[b], last}; ids[a] = ids[b] = last; break; case 1: a = get<1>(cmds[i]); d = get<2>(cmds[i]); if(search(ids[a], d)) cout << "yes\n"; else cout << "no\n"; break; case 2: d = get<1>(cmds[i]); cout << count(d) << "\n"; break; } } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...