Submission #1040658

#TimeUsernameProblemLanguageResultExecution timeMemory
1040658PlurmInside information (BOI21_servers)C++11
87.50 / 100
3547 ms231292 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> using namespace std; using namespace __gnu_pbds; vector<int> g[500005]; vector<int> rg[500005]; int st[500005]; int dep[500005]; int ddep[500005]; int t; int ett[1000005]; int rev[1000005]; 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 < 1000005; 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 pair<int,int> rmq(const int& l, const int& r){ int d = r-l+1; int lg = 31 - __builtin_clz(d); return min(sparse[lg][l], sparse[lg][r-(1<<lg)+1]); } inline int lca(const int& u, const int& v){ if(st[u] > st[v]) return rmq(st[v], st[u]).second; else return rmq(st[u], st[v]).second; } inline bool search(const int& a, const int& d){ int l = lca(a, d); int dist = dep[a] + dep[d] - 2*dep[l]; int ddist = ddep[d] - ddep[a]; return dist == ddist; } tuple<int,int,int> buffer[500005]; int bsz; const int THRESH = 1000; int qs[500005]; int evp[500005]; 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...