树剖全WA求调
查看原帖
树剖全WA求调
605945
luo_xiaoran楼主2024/3/19 07:32
#include<bits/stdc++.h>
#define int long long
#define N (int)1e5+5
using namespace std;
int n,m,cnt,tot,la[N<<2],head[N],a[N],dep[N],na[N],son[N],fat[N],top[N],sz[N],id[N];
struct Edge{
	int u,v,nxt;
}e[N<<1];
void add(int u,int v){
	e[++cnt]=Edge{u,v,head[u]};
	head[u]=cnt;
}
void dfs1(int u,int fa){
	sz[u]=1,fat[u]=fa,dep[u]=dep[fa]+1;
	for(int i=head[u];i;i=e[i].nxt){
		if(e[i].v==fa) continue;
		dfs1(e[i].v,u);
		sz[u]+=sz[e[i].v];
		if(sz[e[i].v]>sz[son[u]]) son[u]=e[i].v;
	}
}
void dfs2(int u){
	id[u]=++tot,na[tot]=a[u];
	if(son[u]) top[son[u]]=top[u],dfs2(son[u]);
	for(int i=head[u];i;i=e[i].nxt){
		if(e[i].v==son[u]||e[i].v==fat[u]) continue;
		top[e[i].v]=e[i].v;
		dfs2(e[i].v);
	}
}
struct Node{
	int lc,rc,d;
}tr[N<<2];
void pushup(int p){
	tr[p].d=tr[p<<1].d+tr[p<<1|1].d-(tr[p<<1].rc==tr[p<<1|1].lc);
	tr[p].lc=tr[p<<1].lc;
	tr[p].rc=tr[p<<1|1].rc;
}
void pushdown(int s,int t,int p){
	int m=(s+t)>>1;
	if(la[p]) na[s]=na[m]=na[m+1]=na[t]=tr[p<<1].d=tr[p<<1|1].d=1,la[p<<1]=la[p<<1|1]=tr[p<<1].lc=tr[p<<1|1].lc=tr[p<<1].rc=tr[p<<1|1].rc=la[p];
	la[p]=0;
}
void build(int s,int t,int p){
	if(s==t){
		tr[p].d=1;
		tr[p].lc=tr[p].rc=na[s];
		return ;
	}
	int m=(s+t)>>1;
	build(s,m,p<<1),build(m+1,t,p<<1|1);
	pushup(p);
}
void update(int l,int r,int s,int t,int c,int p){
	if(l<=s&&t<=r){
		tr[p].d=1;
		tr[p].lc=tr[p].rc=c;
		la[p]=c;
		na[s]=na[t]=c;
		return ;
	}
	pushdown(s,t,p);
	int m=(s+t)>>1;
	if(l<=m) update(l,r,s,m,c,p<<1);
	if(r>m) update(l,r,m+1,t,c,p<<1|1);
	pushup(p);
}
int query(int l,int r,int s,int t,int p){
//	printf("!%d %d %d\n",s,t,tr[p].d);
	if(l<=s&&t<=r) return tr[p].d;
	pushdown(s,t,p);
	int m=(s+t)>>1,v=0;
	if(l<=m) v=query(l,r,s,m,p<<1);
	if(r>m) v+=query(l,r,m+1,t,p<<1|1)-(l<=m&&(tr[p<<1].rc==tr[p<<1|1].lc));
	return v;
}
void update_path(int u,int v,int c){
	while(top[u]^top[v]){
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		update(id[top[u]],id[u],1,n,c,1);
//		printf("U:%lld %lld\n",u,top[u]);
		u=fat[top[u]];
	}
	if(dep[u]<dep[v]) swap(u,v);
//	printf("UU:%lld %lld\n",u,v);
	update(id[v],id[u],1,n,c,1);
}
int query_path(int u,int v){
	int ans=0,x=0,y=0;
	while(top[u]^top[v]){
		if(dep[top[u]]<dep[top[v]]) swap(u,v),swap(x,y);
		if(x) ans-=(na[x]==na[id[u]]);
		ans+=query(id[top[u]],id[u],1,n,1);
		x=id[top[u]];
//		printf("Q:%lld %lld %lld\n",u,top[u],ans);
		u=fat[top[u]];
	}
	if(dep[u]<dep[v]) swap(u,v),swap(x,y);
	ans+=query(id[v],id[u],1,n,1);
	if(x) ans-=(na[x]==na[id[u]]);
	if(y) ans-=(na[y]==na[id[v]]);
//	printf("QQ:%lld %lld %lld\n",u,v,ans);
//	printf("QQQ:%lld\n",query(id[2],id[5],1,n,1));
	return ans;
}
signed main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;++i) scanf("%lld",&a[i]);
	for(int i=1,u,v;i<n;++i) scanf("%lld%lld",&u,&v),add(u,v),add(v,u);
	dfs1(1,0);
	top[1]=1;
	dfs2(1);
	build(1,n,1);
	while(m--){
		char ss[5];
		int a,b,c;
		scanf("%s%lld%lld",ss,&a,&b);
		if(ss[0]=='C'){
			scanf("%lld",&c);
			update_path(a,b,c);
		}
		else printf("%lld\n",query_path(a,b));
	}
	return 0;
}
/*
*/
2024/3/19 07:32
加载中...