小H和游戏

题目链接:小H和游戏


直接寻找满足距离的节点复杂度是O(n^2)的,因为菊花图每次都找n个点。

但是我们可以利用父亲节点的唯一性来做。

维护每个点的贡献。

dp1,当前节点之间被轰炸的次数。
dp2,当前节点的儿子被轰炸的次数。
dp3,当前节点的二级儿子被轰炸的次数。

每次更新一个点的时候,顺便更新父亲即可。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include
//#define int long long
using namespace std;
const int N=1e6+10;
int n,m,dp1[N],dp2[N],dp3[N],f[N];
vector<int> g[N];
void dfs(int x,int fa){
	f[x]=fa;
	for(auto to:g[x])	if(to!=fa)	dfs(to,x);
}
signed main(){
	cin>>n>>m;
	for(int i=1,a,b;i<n;i++)	scanf("%d %d",&a,&b),g[a].push_back(b),g[b].push_back(a);
	dfs(1,0);
	for(int i=1,x,res;i<=m;i++){
		scanf("%d",&x);
		dp1[x]++;
		if(f[x])	dp2[f[x]]++;
		if(f[f[x]])	dp3[f[f[x]]]++;
		if(x==1) res=dp1[x]+dp2[x]+dp3[x];
		else res=dp2[x]+dp3[x]+dp2[f[x]]+dp1[f[x]]+dp1[f[f[x]]];
		printf("%d\n",res);
	}
	return 0;
}

你可能感兴趣的:(计数问题)