求助倍增 + 树上启发式合并 TLE on #8
查看原帖
求助倍增 + 树上启发式合并 TLE on #8
1074583
_Revali_楼主2024/10/14 08:28

record

#include <bits/stdc++.h>
using namespace std;
struct p{
	int k, id;
};
vector<p> v[100005];
vector<int> vc[100005];
int n, m, sz[100005], dep[100005], dfn[100005], hson[100005], pa[100005][20];
int cnt[100005], ans[100005];
bool f[100005];
int dfs(int x, int fa){
	sz[x] = 1;
	pa[x][0] = fa;
	dep[x] = dep[fa] + 1;
	for(int i = 0; i < vc[x].size(); i++){
		int u = vc[x][i];
		if(u != fa){
			sz[x] += dfs(u, x);
			if(sz[u] > sz[hson[x]]) hson[x] = u;
		}
	}
	return sz[x];
}
void modify(int x, int fa, int k){
	cnt[dep[x]] += k;
	for(int i = 0; i < vc[x].size(); i++){
		int u = vc[x][i];
		if(u == fa || f[u]) continue;
		modify(u, x, k);
	}
}
void dfs2(int x, int fa){
	for(int i = 0; i < vc[x].size(); i++){
		int u = vc[x][i];
		if(u == fa || u == hson[x]) continue;
		dfs2(u, x);
	}
	if(hson[x]){
		dfs2(hson[x], x);
		f[hson[x]] = 1;
	}
	modify(x, fa, 1);
	for(int i = 0; i < v[x].size(); i++)
		ans[v[x][i].id] = cnt[v[x][i].k + dep[x]] - 1;
	if(hson[x]) f[hson[x]] = 0;
	modify(x, fa, -1);
}
void painit(){
	for(int i = 1; i <= 19; i++)
		for(int j = 1; j <= n; j++)
			pa[j][i] = pa[pa[j][i - 1]][i - 1];
}
int fly(int x, int d){
	for(int i = 0; i <= 19; i++)
		if((d >> i) & 1)
			x = pa[x][i];
	return x;
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for(int i = 1; i <= n; i++){
		int x;
		cin >> x;
		vc[x].push_back(i);
		vc[i].push_back(x);
	}
	dfs(0, 0);
	painit();
	cin >> m;
	for(int i = 1; i <= m; i++){
		int a, p;
		cin >> a >> p;
		int ap = fly(a, p);
		if(!ap) continue;
		v[ap].push_back({p, i});
	}
	dfs2(0, 0);
	for(int i = 1; i <= m; i++) cout << ans[i] << ' ';
	return 0;
}
2024/10/14 08:28
加载中...