树剖,但0pts
查看原帖
树剖,但0pts
799098
chengzihan620楼主2024/5/14 19:58
#include<bits/stdc++.h>
#define Access using
#define Code namespace
#define Talker std; 
Access Code Talker;
#define int long long
inline int r(){
	int x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<3)+(x<<1)+c-'0';c=getchar();}return x*f;
}
const int maxn=300010;
int add(int x,int y){
	return x+y;
}
struct segtree{
	int tr[maxn<<2],lz[maxn<<2];
	int *og;
	int (*func)(int,int);
	segtree(int a[],int(*fun)(int,int)){
		og=a;
		func=fun;
		memset(tr,0,sizeof tr);
		memset(lz,0,sizeof lz);
	}
	segtree(){
		func=add;
		memset(tr,0,sizeof tr);
		memset(lz,0,sizeof lz);
	}
	~segtree(){
		delete[]og;
	}
	void maintain(int x){
		tr[x]=func(tr[x<<1],tr[x<<1|1]);
	}
	void pushdown(int s,int t,int now){
		int m=(s+t)>>1;
		tr[now<<1]+=lz[now]*(m-s+1);
		tr[now<<1|1]+=lz[now]*(t-m);
		lz[now<<1]+=lz[now];
		lz[now<<1|1]+=lz[now];
		lz[now]=0;
	}
	void bulid(int s,int t,int now){
		if(s==t){
			tr[now]=og[s];
			return;
		}
		int m=(s+t)>>1;
		bulid(s,m,now<<1);
		bulid(m+1,t,now<<1|1);
		maintain(now);
	}
	void modify(int x,int w,int s,int t,int now){
		if(s==t){
			tr[now]=func(tr[now],w);
			return;
		}
		int m=(s+t)>>1;
		if(x<=m)modify(x,w,s,m,now<<1);
		else modify(x,w,m+1,t,now<<1|1);
		maintain(now);
	}
	void update(int l,int r,int w,int s,int t,int now){
		if(l<=s&&t<=r){
			tr[now]+=(t-s+1)*w;
			lz[now]+=w;
			return;
		}
		int m=(s+t)>>1;
		if(lz[now]&&s!=t)
			pushdown(s,t,now);
		if(l<=m)update(l,r,w,s,m,now<<1);
		if(m<r)update(l,r,w,m+1,t,now<<1|1);
		maintain(now);
	}
	int query(int l,int r,int s,int t,int now){
		if(l<=s&&t<=r)
			return tr[now];
		int m=(s+t)>>1,res=0;
		if(lz[now])
			pushdown(s,t,now);
		if(l<=m)res=func(res,query(l,r,s,m,now<<1));
		if(m<r)res=func(res,query(l,r,m+1,t,now<<1|1));
		return res;
	}
};
struct Graph{
	int next[maxn<<1];
	int to[maxn<<1];
	int dis[maxn<<1];
	int h[maxn<<1];
	int cnt;
	Graph(){
		memset(next,0,sizeof next);
		memset(h,0,sizeof h);
		cnt=0;
	}
	void add(int u,int v,int w){
		next[++cnt]=h[u];
		to[cnt]=v;
		dis[cnt]=w;
		h[u]=cnt;
	}
};
struct tree_chains{
	int tp[maxn],dfn[maxn],vs[maxn];
	int son[maxn],fa[maxn],sz[maxn],dp[maxn];	
	int n,idx;
	segtree chains;
	Graph tr;
	tree_chains(){
		memset(tp,0,sizeof tp);
		memset(dfn,0,sizeof dfn);
		memset(son,0,sizeof son);
		memset(fa,0,sizeof fa);
		memset(sz,0,sizeof sz);
		memset(dp,0,sizeof dp);
	}
	void cut(int num,int rt){
		n=num;
		findson(rt,rt);
		setrank(rt,rt);
	}
	void findson(int u,int f){
		dp[u]=dp[f]+1;
		sz[u]=1;
		fa[u]=f;
		for(int i=tr.h[u];i;i=tr.next[i]){
			int v=tr.to[i];
			if(v==f)continue;
			findson(v,u);
			if(sz[son[u]]<sz[v])
				son[u]=v;
			sz[u]+=sz[v];
		}
	}
	void setrank(int u,int t){
		dfn[u]=++idx;
		tp[u]=t;
		if(!son[u])return;
		setrank(son[u],t);
		for(int i=tr.h[u];i;i=tr.next[i]){
			int v=tr.to[i];
			if(v==fa[u]||v==son[u])
				continue;
			setrank(v,v);
		}
	}
	void upd(int u,int v,int c){
		while(tp[u]!=tp[v]){
			if(dp[tp[u]]<dp[tp[v]])swap(u,v);
			chains.update(dfn[tp[u]],dfn[u],c,1,n,1);
			u=fa[tp[u]];
		}
		if(dp[u]<dp[v])swap(u,v);
		chains.update(dfn[v],dfn[u],c,1,n,1);
	}
	int qry(int u,int v){
		int ret=0;
		while(tp[u]!=tp[v]){
			if(dp[tp[u]]<dp[tp[v]])swap(u,v);
			ret=chains.func(ret,chains.query(dfn[tp[u]],dfn[u],1,n,1));
			u=fa[tp[u]];
		}
		if(dp[u]<dp[v])swap(u,v);
		return chains.func(ret,chains.query(dfn[v],dfn[u],1,n,1));
	}
};
int n;
int a[maxn];
tree_chains zkw;
signed main(){
	int n=r();
	for(int i=1;i<=n;i++)
		a[i]=r();
	for(int i=1;i<n;i++){
		int u=r(),v=r();
		zkw.tr.add(u,v,1);
		zkw.tr.add(v,u,1);
	}
	zkw.cut(n,a[1]);
	for(int i=1;i<n;i++){
		zkw.upd(a[i],a[i+1],1);
		zkw.upd(a[i+1],a[i+1],-1);
	}
	for(int i=1;i<=n;i++)
		cout<<zkw.qry(a[i],a[i])<<endl;
	return 0;
}
2024/5/14 19:58
加载中...