/************************************************************** Problem: 3531 User: syh0313 Language: C++ Result: Accepted Time:9804 ms Memory:107564 kb ****************************************************************/ #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <string> #define lch a[n].lc #define rch a[n].rc using namespace std; const int inf=1000000000; const int maxe=200010; const int maxd=100010; int n,q,topt,to[maxe],nt[maxe],st[maxe],c[maxd],w[maxd],root[maxd]; int dep[maxd],fa[maxd],rem[maxd],size[maxd],top[maxd]; int dfn[maxd],line[maxd],dfn_num,cnt; bool f[maxd]; char s[5]; struct tree { int l,r,lc,rc,ma,sum; }a[4000010]; void add( int x, int y) {to[++topt]=y; nt[topt]=st[x]; st[x]=topt;} void dfs1( int x, int d) { f[x]=1; dep[x]=d; size[x]=1; int p=st[x],ma=0; while (p) { if (!f[to[p]]) { fa[to[p]]=x; dfs1(to[p],d+1); size[x]+=size[to[p]]; if (ma<size[to[p]]) {ma=size[to[p]]; rem[x]=to[p];} } p=nt[p]; } } void dfs2( int x) { if (rem[fa[x]]==x) top[x]=top[fa[x]]; else top[x]=x; f[x]=1; dfn[x]=++dfn_num; line[dfn_num]=x; if (rem[x]) dfs2(rem[x]); int p=st[x]; while (p) { if (!f[to[p]]) dfs2(to[p]); p=nt[p]; } } void updata( int n) { a[n].ma=max(a[lch].ma,a[rch].ma); a[n].sum=a[lch].sum+a[rch].sum; } void build_tree( int &n, int l, int r, int lc, int k) { if (!n) n=++cnt; if (l==r && l==lc) {a[n].ma=k; a[n].sum=k; return ;} if (l==r) return ; int mid=(l+r)>>1; if (lc<=mid) build_tree(lch,l,mid,lc,k); else build_tree(rch,mid+1,r,lc,k); updata(n); } int qurymax( int n, int L, int R, int l, int r) { if (L==l && R==r) return a[n].ma; int mid=(L+R)>>1; if (r<=mid) return qurymax(lch,L,mid,l,r); else if (l>=mid+1) return qurymax(rch,mid+1,R,l,r); else return max(qurymax(lch,L,mid,l,mid),qurymax(rch,mid+1,R,mid+1,r)); } int qmax( int x, int y, int col) { int ans=-inf; while (top[x]!=top[y]) { if (dep[top[x]]<dep[top[y]]) swap(x,y); ans=max(ans,qurymax(root[col],1,n,dfn[top[x]],dfn[x])); x=fa[top[x]]; } int l=min(dfn[x],dfn[y]),r=max(dfn[x],dfn[y]); ans=max(ans,qurymax(root[col],1,n,l,r)); return ans; } int qurysum( int n, int L, int R, int l, int r) { if (L==l && R==r) return a[n].sum; int mid=(L+R)>>1; if (r<=mid) return qurysum(lch,L,mid,l,r); else if (l>=mid+1) return qurysum(rch,mid+1,R,l,r); else return qurysum(lch,L,mid,l,mid)+qurysum(rch,mid+1,R,mid+1,r); } int qsum( int x, int y, int col) { int sum=0; while (top[x]!=top[y]) { if (dep[top[x]]<dep[top[y]]) swap(x,y); sum+=qurysum(root[col],1,n,dfn[top[x]],dfn[x]); x=fa[top[x]]; } int l=min(dfn[x],dfn[y]),r=max(dfn[x],dfn[y]); sum+=qurysum(root[col],1,n,l,r); return sum; } int main() { scanf ( "%d%d" ,&n,&q); for ( int i=1;i<=n;i++) scanf ( "%d%d" ,&w[i],&c[i]); for ( int i=1;i<n;i++) { int xx,yy; scanf ( "%d%d" ,&xx,&yy); add(xx,yy); add(yy,xx); } f[1]=1; dfs1(1,1); memset (f,0, sizeof f); dfs2(1); for ( int i=1;i<=n;i++) build_tree(root[c[i]],1,n,dfn[i],w[i]); while (q--) { int xx,yy; scanf ( "%s %d %d" ,s,&xx,&yy); if (s[0]== 'C' && s[1]== 'C' ) { int last=c[xx],now=yy; build_tree(root[now],1,n,dfn[xx],w[xx]); build_tree(root[last],1,n,dfn[xx],0); c[xx]=now; } else if (s[0]== 'C' && s[1]== 'W' ) {build_tree(root[c[xx]],1,n,dfn[xx],yy); w[xx]=yy;} else if (s[0]== 'Q' && s[1]== 'S' ) { printf ( "%d\n" ,qsum(xx,yy,c[xx]));} else if (s[0]== 'Q' && s[1]== 'M' ) { printf ( "%d\n" ,qmax(xx,yy,c[xx]));} } return 0; } |