제출 #1346000

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

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

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_id[region]][r[u]] += region_cnt;
		for(int v : adj[u]) dfs(v, region, region_cnt);
	};
	
	const int block = sqrt(n);
	int rid = 0;
	for(int i = 0; i < rcnt; ++i) {
		if((int)tin_regions[i].size() >= block) {
			region_id[i] = rid++;
			computed.push_back(vector<int>(rcnt));
			dfs(0, i, 0);
		}
	}
	
	while(q--) {
		int u, v; cin >> u >> v;
		--u; --v;
		if((int)tin_regions[u].size() >= block) cout << computed[region_id[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...