调两天了
#include<bits/stdc++.h>
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;
bool tag;
}t[100005<<2|1];
int lastlc,lastrc;
inline void addtag(int x,int l,int r,int w)
{t[x].v=t[x].tag=1,t[x].lc=t[x].rc=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].lc);
addtag(x<<1|1,t[x<<1|1].l,t[x<<1|1].r,t[x].rc);
t[x].tag=false;
}
void bt(int x,int l,int r){
t[x].l=l,t[x].r=r,t[x].tag=t[x].v=0;
if(l==r)
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(t[x].l==l)
lastlc=t[x].lc;
if(t[x].r==r)
lastrc=t[x].rc;
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);
}
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,ans1=-1,ans2=-1;
while(tp[x]!=tp[y]){
if(dp[tp[x]]<dp[tp[y]])
swap(x,y),swap(ans1,ans2);
ans+=query(1,id[tp[x]],id[x])-(ans1==lastrc);
ans1=lastlc;
x=f[tp[x]];
}
if(dp[x]>dp[y])
swap(x,y),swap(ans1,ans2);
return ans+query(1,id[x],id[y])-(ans1==lastrc)-(ans2==lastlc);
}
char op;
int 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;i<=n;i++)
upd(1,id[i],id[i],a[i]);
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;
}