#include<bits/stdc++.h>
using namespace std;
const int N=3e4+1,INF=1e9+1;
int n,q,dep[N],siz[N],f[N],top[N],hson[N],num[N],val[N],rev[N],tot;
vector<int> g[N];
void dfs1(int x)
{
siz[x]=1;
for(int v:g[x])
{
if(v==f[x]) continue;
dep[v]=dep[x]+1;
f[v]=x;
dfs1(v);
siz[x]+=siz[v];
if(siz[v]>siz[hson[x]]) hson[x]=v;
}
}
void dfs2(int x,int tp)
{
top[x]=tp;
num[x]=++tot;
rev[tot]=x;
if(hson[x]) dfs2(hson[x],tp);
for(int v:g[x])
{
if(v==f[x]||v==hson[x]) continue;
dfs2(v,v);
}
}
struct Node
{
int lcol,rcol,numc,lazy;
}st[N<<2];
inline Node tgt(Node l,Node r)
{
Node ret;
if(l.lazy==-1) return r;
if(r.lazy==-1) return l;
ret.lcol=l.lcol;
ret.rcol=r.rcol;
ret.numc=l.numc+r.numc-(l.rcol==r.lcol);
return ret;
}
void build(int o,int l,int r)
{
if(l==r)
{
st[o].lcol=st[o].rcol=val[rev[l]];
st[o].numc=1;
return;
}
int mid=l+r>>1;
build(o<<1,l,mid);
build(o<<1|1,mid+1,r);
st[o]=tgt(st[o<<1],st[o<<1|1]);
// cout<<' '<<o<<' '<<l<<' '<<r<<' '<<rev[l]<<' '<<rev[r]<<' '<<st[o].lcol<<' '<<st[o].rcol<<' '<<st[o].numc<<endl;
}
inline void pushdown(int o)
{
if(st[o].lazy)
{
st[o<<1].lazy=st[o<<1|1].lazy=st[o<<1].lcol=st[o<<1|1].lcol=st[o<<1].rcol=st[o<<1|1].rcol=st[o].lazy;
st[o<<1].numc=st[o<<1|1].numc=1;
}
}
void update(int o,int ql,int qr,int l,int r,int c)
{
pushdown(o);
if(l>=ql&&r<=qr)
{
st[o].lcol=st[o].rcol=st[o].lazy=c;
st[o].numc=1;
return;
}
int mid=l+r>>1;
if(ql<=mid) update(o<<1,ql,qr,l,mid,c);
if(mid<qr) update(o<<1|1,ql,qr,mid+1,r,c);
st[o]=tgt(st[o<<1],st[o<<1|1]);
}
Node query(int o,int l,int r,int ql,int qr)
{
pushdown(o);
if(l>=ql&&r<=qr) return st[o];
int mid=l+r>>1;
Node ret;
ret.lazy=-1;
if(ql<=mid) ret=query(o<<1,l,mid,ql,qr);
if(mid<qr) ret=tgt(query(o<<1|1,mid+1,r,ql,qr),ret);
return ret;
}
inline void color(int u,int v,int c)
{
while(top[u]!=top[v])
{
if(dep[top[u]]>dep[top[v]])
{
update(1,num[top[u]],num[u],1,n,c);
u=f[top[u]];
}
else
{
update(1,num[top[v]],num[v],1,n,c);
v=f[top[v]];
}
}
if(dep[u]>dep[v]) update(1,num[v],num[u],1,n,c);
else update(1,num[u],num[v],1,n,c);
}
inline int tquery(int u,int v)
{
Node uret,vret;
uret.lazy=vret.lazy=-1;
while(top[u]!=top[v])
{
if(dep[top[u]]>dep[top[v]])
{
uret=tgt(uret,query(1,1,n,num[top[u]],num[u]));
u=f[top[u]];
}
else
{
vret=tgt(vret,query(1,1,n,num[top[v]],num[v]));
v=f[top[v]];
}
}
if(dep[u]>dep[v]) uret=tgt(uret,query(1,1,n,num[v],num[u]));
else vret=tgt(vret,query(1,1,n,num[u],num[v]));
swap(vret.lcol,vret.rcol);
return tgt(uret,vret).numc;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>q;
for(int i=1;i<=n;i++) cin>>val[i];
for(int i=1,a,b;i<n;i++)
{
cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
dep[1]=1;
f[1]=1;
dfs1(1);
dfs2(1,1);
build(1,1,n);
char op;
for(int i=0,a,b,c;i<q;i++)
{
cin>>op>>a>>b;
if(op=='C')
{
cin>>c;
color(a,b,c);
}
else cout<<tquery(a,b)<<'\n';
}
return 0;
}
对于样例,如果注释调试信息,那么输出
1
1
1
如果把调试信息还原,那么最后除调试信息会输出
3
1
1
(Windows10自测结果)