求条
查看原帖
求条
639198
Steve_xh楼主2024/2/24 23:02
#include<bits/stdc++.h>
#define int long long
using namespace std;

struct EDGE{
	int to,next;
}e[100005<<1|1];
int n,m,cnt=0,head[100005],a[100005];
inline void addedge(int u,int v){
	e[++cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}

int f[100005],son[100005],sz[100005],tp[100005],dp[100005];
int segcnt=0,id[100005],seg[100005];

void dfs1(int now,int fa){
	f[now]=fa;
	dp[now]=dp[fa]+1;
	sz[now]++;
	for(int i=head[now];i;i=e[i].next){
		if(e[i].to==fa)
			continue;
		dfs1(e[i].to,now);
		sz[now]+=sz[e[i].to];
		if(sz[e[i].to]>=sz[son[now]])
			son[now]=e[i].to;
	}
}
void dfs2(int now,int t){
	tp[now]=t;
	seg[id[now]=++segcnt]=a[now];
	if(!son[now])
		return ;
	dfs2(son[now],t);
	for(int i=head[now];i;i=e[i].next)
		if(e[i].to!=f[now]&&e[i].to!=son[now])
			dfs2(e[i].to,e[i].to);
}

struct SegTree{
	int l,r,v,lc,rc,tag;
}t[100005<<2|1];
inline void addtag(int x,int l,int r,int w)
{t[x].v=1,t[x].lc=t[x].rc=t[x].tag=w;}
inline void pushup(int x)
{t[x].v=t[x<<1].v+t[x<<1|1].v-(t[x<<1].rc==t[x<<1|1].lc),t[x].lc=t[x<<1].lc,t[x].rc=t[x<<1|1].rc;}
inline void pushdown(int x){
	if(!~t[x].tag)
		return ;
	addtag(x<<1,t[x<<1].l,t[x<<1].r,t[x].tag);
	addtag(x<<1|1,t[x<<1|1].l,t[x<<1|1].r,t[x].tag);
	t[x].tag=-1;
}
void bt(int x,int l,int r){
	t[x].l=l,t[x].r=r,t[x].tag=-1;
	if(l==r){
		t[x].lc=seg[l];
		t[x].rc=seg[r];
		t[x].v=1;
		return ;
	}
	int mid=(l+r)>>1;
	bt(x<<1,l,mid);
	bt(x<<1|1,mid+1,r);
	pushup(x);
}
void upd(int x,int l,int r,int w){
	if(l<=t[x].l&&t[x].r<=r)
		return addtag(x,t[x].l,t[x].r,w);
	pushdown(x);
	int mid=(t[x].l+t[x].r)>>1;
	if(l<=mid)
		upd(x<<1,l,r,w);
	if(mid<r)
		upd(x<<1|1,l,r,w);
	pushup(x);
}
int query(int x,int l,int r){
	if(l<=t[x].l&&t[x].r<=r)
		return t[x].v;
	pushdown(x);
	int mid=(t[x].l+t[x].r)>>1,ans=0;
	if(l<=mid)
		ans+=query(x<<1,l,r);
	if(mid<r)
		ans+=query(x<<1|1,l,r);
	return ans-(l<=mid&&mid<r)*(t[x<<1].rc==t[x<<1|1].lc);
}
int getcolor(int x,int w){
	if(t[x].l==t[x].r)
		return t[x].lc;
	pushdown(x);
	int mid=(t[x].l+t[x].r)>>1;
	if(w<=mid)
		return getcolor(x<<1,w);
	else
		return getcolor(x<<1|1,w);
}

void opC(int x,int y,int w){
	while(tp[x]!=tp[y]){
		if(dp[tp[x]]<dp[tp[y]])
			swap(x,y);
		upd(1,id[tp[x]],id[x],w);
		x=f[tp[x]];
	}
	if(dp[x]>dp[y])
		swap(x,y);
	upd(1,id[x],id[y],w);
} 
int opQ(int x,int y){
	int ans=0,lastx=-1,lasty=-1;
	while(tp[x]!=tp[y]){
		if(dp[tp[x]]<dp[tp[y]])
			swap(x,y),swap(lastx,lasty);
		ans+=query(1,id[tp[x]],id[x])-(lastx==getcolor(1,id[x]));
		lastx=getcolor(1,id[tp[x]]);
		x=f[tp[x]];
	}
	if(dp[x]>dp[y])
		swap(x,y),swap(lastx,lasty);
	return ans+query(1,id[x],id[y])-(lastx==getcolor(1,id[y]))-(lasty==getcolor(1,id[x]));
}

char op;

signed main(){
	cin.tie(0)->sync_with_stdio(false);
	cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	for(int i=1,u,v;i<n;i++)
		cin>>u>>v,addedge(u,v),addedge(v,u);
	dfs1(1,1);
	dfs2(1,1);
	bt(1,1,segcnt);
	for(int i=1,x,y,z;i<=m;i++){
		cin>>op>>x>>y;
		if(op=='C')
			cin>>z,opC(x,y,z);
		else
			cout<<opQ(x,y)<<endl;
	}
	return 0;
}
2024/2/24 23:02
加载中...