Submission #558816

#TimeUsernameProblemLanguageResultExecution timeMemory
558816heavylightdecompRegions (IOI09_regions)C++14
55 / 100
2338 ms131072 KiB
#include<bits/stdc++.h> using namespace std; #define ll long long const int mxN = 2e5+5, mxR = 25005; int reg[mxN], place[mxN], timer, st[mxN], en[mxN], pref[mxN]; vector<int> tr[mxN], inr[mxN], cans[mxN], pans[mxN], vis[mxN]; vector<pair<int,int>> rev[mxN]; vector<pair<int,int>> all; const int bsz = 1024; void euler(int x, int p) { st[x] = ++timer; place[timer] = reg[x]; for(auto it : tr[x]) if(it != p) euler(it, x); en[x] = timer; } signed main() { //freopen("regions.in", "r", stdin); //freopen("regions.out", "w", stdout); int N, R, Q; cin >> N >> R >> Q; cin >> reg[1]; inr[reg[1]].push_back(1); for(int i = 2; i <= N; i++) { int s, h; cin >> s >> h; reg[i] = h; tr[s].push_back(i); tr[i].push_back(s); inr[h].push_back(i); } euler(1, -1); for(int i = 1; i <= N; i++) all.push_back({st[i], i}); sort(all.begin(), all.end()); for(int r = 1; r <= R; r++) { for(auto it : inr[r]) rev[r].push_back({st[it], 0}), rev[r].push_back({en[it]+1, 1}), vis[r].push_back(st[it]); sort(rev[r].begin(), rev[r].end()); sort(vis[r].begin(), vis[r].end()); } for(int r = 1; r <= R; r++) { if(inr[r].size() > bsz) { cans[r] = pans[r] = vector<int> (mxN); for(int i = 0; i < mxN; i++) pref[i] = 0; for(auto bad : vis[r]) pref[bad]++; for(int i = 1; i < mxN; i++) pref[i] += pref[i-1]; #define get(l,r) (pref[(r)]-(((l)>0)?pref[(l)-1]:0)) for(int k = 1; k <= R; k++) { if(k==r) continue; for(auto member : inr[k]) cans[r][k] += get(st[member], en[member]); } int j = 0; int active = 0; for(int c = 1; c <= N; c++) { while(j < int(rev[r].size()) && rev[r][j].first <= c) { if(rev[r][j].second) active--; else active++; j++; } pans[r][place[c]] += active; } } } for(int g = 1; g <= Q; g++) { int a, b; cin >> a >> b; if(inr[reg[a]].size() > bsz) { cout << pans[a][b] << endl; } else if(inr[reg[b]].size() > bsz) { cout << cans[b][a] << endl; } else { int j = 0, active = 0, res = 0; for(int ct : vis[b]) { while(j < int(rev[a].size()) && rev[a][j].first <= ct) { if(rev[a][j].second) active--; else active++; j++; } res += active; } cout << res << endl; } } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...