树上差分 10pts 求调qwq
查看原帖
树上差分 10pts 求调qwq
1207677
MassPoint楼主2025/2/2 11:20

rt.

#include<bits/stdc++.h>
using namespace std;
int n;
int a[300100];
int num[300100];
vector < vector <int> > e;
int deep[300100];
int lg[300100];
int fa[300100][51];
void dfs(int fat,int u){
	fa[u][0]=fat,deep[u]=deep[fat]+1;
	for(int i=1;i<=lg[u]+1;i++)
		fa[u][i]=fa[fa[u][i-1]][i-1];
	for(int i=0;i<e[u].size();i++)
		if(e[u][i]!=fat)	dfs(u,e[u][i]);
}
int lca(int x,int y){
	if(deep[x]<deep[y])	swap(x,y);
	while(deep[x]>deep[y])	x=fa[x][lg[deep[x]-deep[y]]];
	if(x==y)	return x;
	for(int i=lg[deep[x]];i>=0;i--)
		if(fa[x][i]!=fa[y][i])	x=fa[x][i],y=fa[y][i];
	return fa[x][0];
}
void init(){
	for(int i=1;i<=n;i++)
		lg[i]=lg[i-1]+((1<<lg[i-1])==i);
	for(int i=1;i<=n;i++)
		lg[i]--;
	dfs(0,1);
}
void ans(int u,int fat){
	for(int i=0;i<e[u].size();i++)
		if(e[u][i]!=fat){
			ans(e[u][i],u);
			num[u]+=num[e[u][i]];
		}	
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)	scanf("%d",a+i);
	e.resize(n+1);
	for(int i=1;i<n;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		e[u].push_back(v),e[v].push_back(u);
	}
	init();
	for(int i=1;i<n;i++){
		int u=a[i],v=a[i+1];
		int t=lca(u,v);
		num[fa[t][0]]--;
		num[t]--;
		num[u]++;
		num[v]++;
	}
	ans(1,0);
	for(int i=2;i<=n;i++)	num[a[i]]--;
	for(int i=1;i<=n;i++)	printf("%d\n",num[i]);
	return 0;	
}
2025/2/2 11:20
加载中...