제출 #1345988

#제출 시각아이디문제언어결과실행 시간메모리
1345988prism7kRegions (IOI09_regions)C++20
95 / 100
3257 ms140268 KiB
#include <bits/stdc++.h>
using namespace std;

const int MAXN = 2e5;
vector<vector<int>> adj(MAXN);
vector<int> r(MAXN);
vector<vector<int>> tin_regions(MAXN);
vector<int> tin(MAXN), tout(MAXN), tin_to_node(MAXN);
int timer = 0;
map<int, map<int, int>> computed;

int main() {
	int n, rcnt, q; cin >> n >> rcnt >> q;
	cin >> r[0];
	--r[0];
	for(int i = 1; i <= n - 1; ++i) {
		int p, h; cin >> p >> h;
		--p; --h;
		r[i] = h;
		adj[p].push_back(i);
	}
	
	function<void(int, int)> euler = [&](int u, int p) -> void {
		tin_regions[r[u]].push_back(timer);
		tin_to_node[timer] = u;
		tin[u] = timer++;
		for(int v : adj[u]) {
			if(v == p) continue;
			euler(v, u);
		}
		tout[u] = timer;
	};
	euler(0, -1);
	
	function<void(int, int, int)> dfs = [&](int u, int region, int region_cnt) -> void {
		if(r[u] == region) region_cnt++;
		else computed[region][r[u]] += region_cnt;
		for(int v : adj[u]) dfs(v, region, region_cnt);
	};
	
	const int block = sqrt(n);
	for(int i = 0; i < rcnt; ++i) {
		if((int)tin_regions[i].size() >= block) {
			dfs(0, i, 0);
		}
	}
	
	while(q--) {
		int u, v; cin >> u >> v;
		--u; --v;
		if((int)tin_regions[u].size() >= block) cout << computed[u][v] << "\n";
		else {
			int res = 0;
			for(int t : tin_regions[u]) {
				int node = tin_to_node[t];
				res +=
					lower_bound(tin_regions[v].begin(), tin_regions[v].end(), tout[node]) -
					lower_bound(tin_regions[v].begin(), tin_regions[v].end(), tin[node]);
			}
			cout << res << "\n";
		}
	}
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...