# include <bits/stdc++.h> using namespace std;
const int N = 1e5+7;
/***************************************/
int n,m; int c[N]; vector<int >G[N];
int fa[N],sz[N],son[N],dep[N];
int dfs1(int u,int f,int d){ fa[u]=f,sz[u]=1,son[u]=0,dep[u]=d; int gz = G[u].size(); for(int to,i=0;i<gz;i++){ to = G[u][i]; if(to==f) continue; dfs1(to,u,d+1); sz[u]+=sz[to]; if(sz[son[u]]<sz[to]) son[u]=to; } }
int top[N],tree[N],pre[N],cnt;
int dfs2(int u,int tp){ top[u]=tp,tree[u]=++cnt,pre[tree[u]]=u; if(son[u]) dfs2(son[u],tp); int gz = G[u].size(); for(int to,i=0;i<gz;i++){ to = G[u][i]; if(to==fa[u]||to==son[u])continue; dfs2(to,to); } }
int sum[N<<2],lazy[N<<2],lc[N<<2],rc[N<<2];
void pushup(int rt){ sum[rt] = sum[rt<<1]+sum[rt<<1|1]-(rc[rt<<1] == lc[rt<<1|1]); lc[rt]=lc[rt<<1],rc[rt]=rc[rt<<1|1]; }
void pushdown(int rt){ if(lazy[rt]!=-1){ lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt]; sum [rt<<1] = sum [rt<<1|1] = 1; lc[rt<<1] = rc[rt<<1] = lazy[rt]; lc[rt<<1|1] = rc[rt<<1|1] = lazy[rt]; lazy[rt]=-1; } }
void build(int rt,int l,int r){ if(l==r){ sum[rt]=1,rc[rt]=lc[rt]=c[pre[l]]; return ; } int m = (r+l)>>1; build(rt<<1 ,l ,m); build(rt<<1|1,m+1,r); pushup(rt); }
void update(int rt,int l,int r,int L,int R,int clr){ if(L<=l&&r<=R){ rc[rt]=lc[rt]=lazy[rt]=clr; sum[rt] = 1; return ; } pushdown(rt); int m = (r+l)>>1; if(L<=m) update(rt<<1 ,l ,m,L,R,clr); if(R> m) update(rt<<1|1,m+1,r,L,R,clr); pushup(rt); return ; }
int query(int rt,int l,int r,int L,int R){ if(L>R) return 0; if(L<=l&&r<=R) return sum[rt]; pushdown(rt); int ans = 0,m = (r+l)>>1; if(R<=m) ans = query(rt<<1 ,l, m,L,R); else if(L>m) ans = query(rt<<1|1,m+1,r,L,R); else ans = query(rt<<1 ,l, m,L,R)+ query(rt<<1|1,m+1,r,L,R)- (rc[rt<<1]==lc[rt<<1|1]); pushup(rt); return ans; }
int query_color(int rt,int l,int r,int pos){ if(l==r) return lc[rt]; pushdown(rt); int m = (r+l)>>1,ans; if(pos<=m) ans = query_color(rt<<1 ,l ,m,pos); else ans = query_color(rt<<1|1,m+1,r,pos); pushup(rt); return ans; }
void init(){ cnt = 0; for(int i=1;i<=n;i++)G[i].clear(); memset(sum,0,sizeof(sum)); memset(lazy,-1,sizeof(lazy)); };
void brush(int x,int y,int clr){ int fx = top[x],fy = top[y]; while(fx!=fy){ if(dep[fx]<dep[fy]) swap(fx,fy),swap(x,y); update(1,1,n,tree[fx],tree[x],clr); x = fa[fx],fx = top[x]; } if(tree[x]>tree[y]) swap(x,y); update(1,1,n,tree[x],tree[y],clr); return ; }
void solve(int x,int y){ int fx = top[x],fy = top[y]; int ans = 0; while(fx!=fy){ if(dep[fx]<dep[fy]) swap(fx,fy),swap(x,y); ans += query(1,1,n,tree[fx],tree[x]); if(query_color(1,1,n,tree[fa[fx]]) == query_color(1,1,n,tree[fx])) ans--; x = fa[fx],fx = top[x]; } if(tree[x]>tree[y]) swap(x,y); ans += query(1,1,n,tree[x],tree[y]); printf("%d\n",ans); return ; }
int main(){ while(~scanf("%d%d",&n,&m)){ init();
for(int i=1;i<=n;i++) scanf("%d",&c[i]);
for(int i=2,u,v;i<=n;i++){ scanf("%d %d",&u,&v); G[u].push_back(v); G[v].push_back(u); }
dfs1(1,-1,1); dfs2(1,1); build(1,1,n);
int l,r,x; char a[10]; while(m--){ scanf("%s",a); scanf("%d %d",&l,&r); if(a[0]=='C'){ scanf("%d",&x); brush(l,r,x); } else solve(l,r); } } return 0; }
|