过样例+0分
#include<iostream>
using namespace std;
struct segment{
int sum;
int ping;
int Lcol,Rcol;
int l,r,mid,S;
void clear(){
S=ping=l=r=mid=Lcol=Rcol=sum=0;
}
};
segment rev(segment a){
swap(a.Lcol,a.Rcol);
return a;
}
int a[100001],A[100001],n,m;
segment t[400001];
segment operator +(segment a,segment b){
segment c;
c.clear();
if(a.S==0) c=b;
else if(b.S==0) c=a;
else{
c.l=a.l,c.r=b.r;
c.Lcol=a.Lcol,c.Rcol=b.Rcol;
c.sum=a.sum+b.sum-(a.Rcol==b.Lcol);
c.mid=c.l+c.r>>1;
c.S=c.r-c.l+1;
c.S=a.S+b.S;
}
return c;
}
void pushup(int p){
t[p]=t[p<<1]+t[p<<1|1];
}
void build(int *A,int p,int l,int r){
if(l==r) t[p].sum=1,t[p].l=t[p].r=r,t[p].Lcol=t[p].Rcol=A[l],t[p].S=1;
else{
build(A,p<<1,l,l+r>>1),build(A,p<<1|1,(l+r>>1)+1,r);
pushup(p);
}
}
void give(int p,int k){
t[p].Lcol=t[p].Rcol=k;
t[p].sum=1;
t[p].ping=k;
}
void pushdown(int p){
if(t[p].ping==0) return;
cout<<p<<endl;
give(p<<1,t[p].ping),give(p<<1|1,t[p].ping);
t[p].ping=0;
}
void UPDATE(int p,int L,int R,int k){
if(t[p].l>=L&&t[p].r<=R) give(p,k);
else{
pushdown(p);
if(t[p].mid>=L) UPDATE(p<<1,L,R,k);
if(t[p].mid<R) UPDATE(p<<1|1,L,R,k);
pushup(p);
}
}
segment QUERY(int p,int L,int R){
if(t[p].l>=L&&t[p].r<=R) return t[p];
else{
pushdown(p);
segment sum;
sum.clear();
if(t[p].mid>=L) sum=sum+QUERY(p<<1,L,R);
if(t[p].mid<R) sum=sum+QUERY(p<<1|1,L,R);
return sum;
}
}
int head[100001],Nxt[200001],ver[200001],edge[200001],tot,cnt;
int top[100001],depth[100001],son[100001];
int S[100001],id[100001],fa[100001];
void add(int x,int y){
ver[++tot]=y;
Nxt[tot]=head[x];
head[x]=tot;
}
void H_DFS(int x,int F){
fa[x]=F;S[x]=1;
int maxson=0;
for(int i=head[x];i;i=Nxt[i]){
int y=ver[i];
if(y==F) continue;
depth[y]=depth[x]+1;
H_DFS(y,x);
S[x]+=S[y];
if(S[y]>maxson) maxson=S[y],son[x]=y;
}
}
void ID_DFS(int x,int root){
top[x]=root;id[x]=++cnt;
A[cnt]=a[x];
if(son[x]==0) return;
ID_DFS(son[x],root);
for(int i=head[x];i;i=Nxt[i]){
int y=ver[i];
if(y==fa[x]||y==son[x]) continue;
ID_DFS(y,y);
}
}
void L_UPDATE(int x,int y,int k){
while(top[x]!=top[y]){
if(depth[top[x]]<depth[top[y]]) swap(x,y);
UPDATE(1,id[top[x]],id[x],k);
x=fa[top[x]];
}
if(depth[x]>depth[y]) swap(x,y);
UPDATE(1,id[x],id[y],k);
}
int L_QUERY(int x,int y){
segment sum1,sum2;
sum1.clear(),sum2.clear();
while(top[x]!=top[y]){
if(depth[top[x]]<depth[top[y]]){
sum2=QUERY(1,id[top[y]],id[y])+sum2;
y=fa[top[y]];
}
else{
sum1=sum1+QUERY(1,id[top[x]],id[x]);
x=fa[top[x]];
}
}
if(depth[x]>depth[y]) sum2=QUERY(1,id[y],id[x])+sum2;
else sum1=sum1+QUERY(1,id[x],id[y]);
return (sum1+rev(sum2)).sum;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;++i) cin>>a[i];
for(int i=1;i<n;++i){
int x,y;
cin>>x>>y;
add(x,y);
add(y,x);
}
depth[1]=1;
H_DFS(1,0);
ID_DFS(1,1);
build(A,1,1,cnt);
while(m--){
char op;
cin>>op;
if(op=='C'){
int l,r,k;
cin>>l>>r>>k;
L_UPDATE(l,r,k);
}
else{
int l,r;
cin>>l>>r;
cout<<L_QUERY(l,r)<<endl;
}
}
}