RT,样例过了。结构体里 v 是颜色段数,sc、tc 是左右端点颜色。
#include<bits/stdc++.h>
#define int long long
#define cyq int
using namespace std;
const int maxn=500005;
int d[maxn],s[maxn],t[maxn],dfn[maxn],rk[maxn],sz[maxn],fa[maxn],cnt,n,q,k,a[maxn];
struct sgt{
int v,sc,tc,tg;
}tre[maxn<<2];
cyq mod;
vector<int> g[maxn];
void pu(int id)
{
tre[id].v=tre[id*2].v+tre[id*2+1].v-(tre[id*2].tc==tre[id*2+1].sc);
tre[id].sc=tre[id*2].sc;
tre[id].tc=tre[id*2+1].tc;
}
void pd(int s,int t,int id)
{
int m=(s+t)>>1;
if (s!=t && tre[id].tg){
tre[id*2].v=tre[id*2+1].v=1;
tre[id*2].sc=tre[id*2].tc=tre[id*2+1].sc=tre[id*2+1].tc=tre[id].tg;
tre[id*2].tg=tre[id*2+1].tg=tre[id].tg;
tre[id*2].tg=0;
}
}
void upd(int l,int r,int s,int t,int id,int k)
{
if (l<=s && t<=r){
tre[id].v=1;
tre[id].sc=tre[id].tc=tre[id].tg=k;
return ;
}
pd(s,t,id);
int m=(s+t)/2;
if (m>=l){
upd(l,r,s,m,id*2,k);
}
if (m<r){
upd(l,r,m+1,t,id*2+1,k);
}
pu(id);
}
sgt ask(int l,int r,int s,int t,int id)
{
if (l<=s && t<=r){
return tre[id];
}
pd(s,t,id);
int m=(s+t)/2;
sgt sum;
sum.v=sum.tc=sum.sc=0;
if (m>=l){
sum=ask(l,r,s,m,id*2);
}
if (m<r){
sgt k=ask(l,r,m+1,t,id*2+1);
if (!sum.v){
sum=k;
}else{
sum.v=sum.v+k.v-(sum.tc==k.sc);
sum.tc=k.tc;
}
}
pu(id);
return sum;
}
void dfs1(int u)
{
sz[u]=1;
for (int v:g[u]){
if (!d[v]){
d[v]=d[u]+1;
fa[v]=u;
dfs1(v);
sz[u]+=sz[v];
if (sz[v]>sz[s[u]]){
s[u]=v;
}
}
}
}
void dfs2(int u,int hd)
{
t[u]=hd;
dfn[u]=++cnt;
rk[cnt]=u;
if (!s[u]){
return ;
}
dfs2(s[u],hd);
for (int v:g[u]){
if (v==s[u] || v==fa[u]){
continue;
}
dfs2(v,v);
}
}
void tupd(int u,int v,int k)
{
while (t[u]!=t[v]){
if (d[t[u]]<d[t[v]]){
swap(u,v);
}
upd(dfn[t[u]],dfn[u],1,n,1,k);
u=fa[t[u]];
}
if (d[u]>d[v]){
swap(u,v);
}
upd(dfn[u],dfn[v],1,n,1,k);
}
int task(int u,int v)
{
int sum=0,c1=0,c2=0;
while (t[u]!=t[v]){
if (d[t[u]]<d[t[v]]){
swap(u,v);
swap(c1,c2);
}
sgt k=ask(dfn[t[u]],dfn[u],1,n,1);
sum+=k.v;
if (c1==k.sc){
sum--;
}
u=fa[t[u]];
c1=k.sc;
}
if (d[u]>d[v]){
swap(u,v);
swap(c1,c2);
}
sgt k=ask(dfn[u],dfn[v],1,n,1);
sum+=k.v;
if (c1==k.sc){
sum--;
}
if (c2==k.tc){
sum--;
}
return sum;
}
signed main()
{
cin>>n>>q;
k=1;
for (int i=1;i<=n;i++){
cin>>a[i];
}
for (int i=1;i<n;i++){
int u,v;
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
fa[k]=k;
d[k]=1;
dfs1(k);
dfs2(k,k);
for (int i=1;i<=n;i++){
upd(dfn[i],dfn[i],1,n,1,a[i]);
}
while (q--){
char op;
int u,v;
cin>>op>>u>>v;
if (op=='C'){
int k;
cin>>k;
tupd(u,v,k);
}else{
cout<<task(u,v)<<endl;
}
}
}