Code:
#include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) , freopen(s".out","w",stdout) #define maxn 300000 using namespace std; struct OPT { int type; int a,b,c,tag; OPT(int type=0,int a=0,int b=0,int c=0,int tag=0):type(type),a(a),b(b),c(c),tag(tag){} }opt[maxn]; vector<OPT>G[maxn]; struct BIT { #define N 300000 int C[maxn]; int lowbit(int t) { return t & (-t); } void update(int x,int delta) { while(x<N) { C[x]+=delta; x+=lowbit(x); } } int query(int x) { int tmp=0; while(x>0) { tmp+=C[x]; x-=lowbit(x); } return tmp; } }tree; char str[10]; int n, Q, edges, tot, tim, dk = 0; int col[maxn],Arr[maxn],hd[maxn],to[maxn<<1],nex[maxn<<1],dfn[maxn],ln[maxn],st[maxn],ed[maxn]; int siz[maxn],hson[maxn],dep[maxn],top[maxn],fa[maxn],answer[maxn]; void add(int u,int v) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } void dfs1(int u,int ff) { ln[++tim]=u,dfn[u]=st[u]=tim,siz[u]=1,dep[u]=dep[ff]+1,fa[u]=ff; for(int i=hd[u];i;i=nex[i]) { int v=to[i]; if(v==ff) continue; dfs1 (v, u); [u] + = [c]; if (you [v]> you [hson [u]]) hson [u] = v; } ed[u]=tim; } void dfs2(int u,int tp) { top[u]=tp; if(hson[u]) dfs2(hson[u],tp); for(int i=hd[u];i;i=nex[i]) { int v=to[i]; if(v==fa[u]||v==hson[u]) continue; dfs2 (v, v); } } int LCA(int x,int y) { while(top[x]^top[y]) dep[top[x]] > dep[top[y]] ? x = fa[top[x]] : y = fa[top[y]]; return shallow [x] <shallow [y]? x: y; } void solve(int cur) { for(int i=0,sz=G[cur].size();i<sz;++i) { OPT cn=G[cur][i]; switch(cn.type) { case -1: { int u=cn.a; tree.update(st[u], -1); tree.update(ed[u]+1, +1); break; } case 1 : { int u=cn.a; tree.update(st[u], 1); tree.update(ed[u]+1, -1); break; } case 2 : { int u=cn.a; int y = cn.b; int c = CN.CO; int g=cn.tag; int lca = LCA(u,v); answer[g]=tree.query(dfn[u])+tree.query(dfn[v])-tree.query(dfn[lca])-tree.query(dfn[fa[lca]]); break; } } } for(int i=0,sz=G[cur].size();i<sz;++i) { OPT cn=G[cur][i]; if(cn.type==-1) tree.update(st[cn.a], +1), tree.update(ed[cn.a]+1,-1); if(cn.type==1) tree.update(st[cn.a], -1), tree.update(ed[cn.a]+1, +1); } } int main () { // setIO("input"); scanf("%d%d",&n,&Q); for(int i=1;i<=n;++i) scanf("%d",&col[i]),Arr[++tot]=col[i]; for(int i=1;i<n;++i) { int x,y; scanf("%d%d",&x,&y); add(x,y), add(y,x); } dfs1 (1.0); dfs2(1,1); for(int i=1;i<=Q;++i) { scanf("%s",str); switch(str[0]) { case 'C' : { opt[i].type=1; scanf("%d%d",&opt[i].a,&opt[i].b); Arr [++ to] opt = [i] .b; break; } case 'Q' : { opt[i].type=2; scanf("%d%d%d",&opt[i].a,&opt[i].b,&opt[i].c); Arr [++ to] opt = [i] .c; break; } } } sort (Arr + 1, + 1 + Arr to); for(int i=1;i<=Q;++i) { if(opt[i].type==1) opt[i].b=lower_bound(Arr+1,Arr+1+tot,opt[i].b)-Arr; if(opt[i].type==2) opt[i].c=lower_bound(Arr+1,Arr+1+tot,opt[i].c)-Arr; } for(int i=1;i<=n;++i) { col[i]=lower_bound(Arr+1,Arr+1+tot,col[i])-Arr; G[col[i]].push_back(OPT(1,i,0,0,0)); } for(int i=1;i<=Q;++i) { if(opt[i].type==2) { OPT P=opt[i]; Pd = ++ mkk; G[opt[i].c].push_back(P); } else { int u=opt[i].a,v=opt[i].b; G[col[u]].push_back(OPT(-1,u,0,0,0)); G[v].push_back(OPT(1,u,0,0,0)); col[u]=v; } } for(int i=1;i<maxn;++i) { if(G[i].size()) solve(i); } for(int i=1;i<=mkk;++i) { printf("%d\n",answer[i]); } return 0; }