树链剖分60分,求调
查看原帖
树链剖分60分,求调
755574
ZXZ_楼主2024/2/26 19:28
#include<cstdio>
#define N 300001
int n,a[N],head[N],tot,rank[N],cntdfn;
struct edge{int to,nxt;}e[N*2];
struct Tree{int dfn,w,siz,fa,dep,son,top;}Tr[N];
struct SegTree{
	struct ST{int lazy,s;}tr[N*4];
	void pushdown(int l,int r,int x){
		int mid=l+r>>1;
		tr[x<<1].s+=(mid-l+1)*tr[x].lazy;
		tr[x<<1].lazy+=tr[x].lazy;
		tr[x<<1|1].s+=(r-mid)*tr[x].lazy;
		tr[x<<1|1].lazy+=tr[x].lazy;
		tr[x].lazy=0;
	}
	void update(int l,int r,int s,int t,int x,int k){
		if(s>=l&&t<=r){
			tr[x].s+=(t-s+1)*k;
			tr[x].lazy+=k;
			return;
		}
		if(tr[x].lazy)pushdown(s,t,x);
		int mid=s+t>>1;
		if(l<=mid)update(l,r,s,mid,x<<1,k);
		if(r>mid)update(l,r,mid+1,t,x<<1|1,k);
		tr[x].s=tr[x<<1].s+tr[x<<1|1].s;
	}
	int query(int l,int r,int s,int t,int x){
		if(s>=l&&t<=r)return tr[x].s;
		if(tr[x].lazy)pushdown(s,t,x);
		int mid=s+t>>1;
		int ans=0,ans1=0;
		if(l<=mid)ans=query(l,r,s,mid,x<<1);
		if(r>mid)ans1=query(l,r,mid+1,t,x<<1|1);
		return ans+ans1;
	}
}T;
void add(int u,int v){
	e[++tot].to=v;
	e[tot].nxt=head[u];
	head[u]=tot;
}
void DFS(int x){
	Tr[x].son=-1;
	Tr[x].siz=1;
	for(int i=head[x];i;i=e[i].nxt)
		if(!Tr[e[i].to].dep){
			Tr[e[i].to].dep=Tr[x].dep+1;
			Tr[e[i].to].fa=x;
			DFS(e[i].to);
			Tr[x].siz+=Tr[e[i].to].siz;
			if(Tr[x].son==-1||Tr[e[i].to].siz>Tr[Tr[x].son].siz)Tr[x].son=e[i].to;
		}
}
void DFS1(int x,int top){
	Tr[x].top=top;
	++cntdfn;
	Tr[x].dfn=cntdfn;
	rank[cntdfn]=x;
	if(Tr[x].son==-1)return;
	DFS1(Tr[x].son,top);
	for(int i=head[x];i;i=e[i].nxt)
		if(e[i].to!=Tr[x].son&&e[i].to!=Tr[x].fa)
			DFS1(e[i].to,e[i].to);
}
void Update(int x,int y){
	int fx=Tr[x].top,fy=Tr[y].top;
	while(fx!=fy){
		if(Tr[fx].dep>=Tr[fy].top)T.update(Tr[fx].dfn,Tr[x].dfn,1,n,1,1),x=Tr[fx].fa;
		else T.update(Tr[fy].dfn,Tr[y].dfn,1,n,1,1),y=Tr[fy].fa;
		fx=Tr[x].top;
		fy=Tr[y].top;
	}
	if(Tr[x].dfn<Tr[y].dfn)T.update(Tr[x].dfn,Tr[y].dfn,1,n,1,1);
	else T.update(Tr[y].dfn,Tr[x].dfn,1,n,1,1);
	return;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",a+i);
	for(int i=1;i<n;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v);
		add(v,u);	
	}
	Tr[1].dep=1;
	DFS(1);
	DFS1(1,1);
	for(int i=1;i<n;i++)Update(a[i],a[i+1]),T.update(Tr[a[i+1]].dfn,Tr[a[i+1]].dfn,1,n,1,-1);
	for(int i=1;i<=n;i++)printf("%d\n",T.query(Tr[i].dfn,Tr[i].dfn,1,n,1));
}
2024/2/26 19:28
加载中...