#include<bits/stdc++.h>
#define int long long
#define mem(a) memset(a,0,sizeof(a))
#define set(a,b) memset(a,b,sizeof(a))
#define ls i<<1
#define rs i<<1|1
#define pb push_back
#define pt putchar
#define All(a) a.begin(),a.end()
#define T int t;cin>>t;while(t--)
#define rand RAND
using namespace std;
char buf[1<<20],*p1,*p2;
#define gc()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
template<class Typ> Typ &re(Typ &x){char ch=gc(),sgn=0; x=0;for(;ch<'0'||ch>'9';ch=gc()) sgn|=ch=='-';for(;ch>='0'&&ch<='9';ch=gc()) x=x*10+(ch^48);return sgn&&(x=-x),x;}
template<class Typ> void wt(Typ x){if(x<0) putchar('-'),x=-x;if(x>9) wt(x/10);putchar(x%10^48);}
const int inf=0x3f3f3f3f3f;
const int maxn=1e5+5;
const int mod=1e9+7;
int seed = 19243;
unsigned rand(){return seed=(seed*48271ll)%2147483647;}
int n,m;
int a[maxn];
vector<int>G[maxn];
int fa[maxn],dep[maxn],sz[maxn],son[maxn];
void dfs(int u,int f){
son[u]=-1;
fa[u]=f;
dep[u]=dep[f]+1;
sz[u]=1;
for(int v:G[u]){
if(v==f)continue;
dfs(v,u);
sz[u]+=sz[v];
if(sz[v]>sz[son[u]]||son[u]==-1)son[u]=v;
}
}
int idx,dfn[maxn],top[maxn],rnk[maxn];
int col[maxn];
void dfs1(int u,int tp){
top[u]=tp;
dfn[u]=++idx;
rnk[idx]=u;
col[idx]=a[u];
if(son[u]==-1)return ;
dfs1(son[u],tp);
for(int v:G[u]){
if(v==son[u] or v==fa[u])continue;
dfs1(v,v);
}
}
struct Seg{
int sum[maxn<<2],tag[maxn<<2];
void push_up(int i,int mid){
sum[i]=sum[ls]+sum[rs];
if(col[mid]==col[mid+1])sum[i]--;
return ;
}
void build(int l,int r,int i){
if(l==r){
sum[i]=1;
return ;
}
int mid=(l+r)>>1;
build(l,mid,ls);
build(mid+1,r,rs);
push_up(i,mid);
}
void push_down(int i,int mid){
if(!tag[i])return ;
tag[ls]=tag[rs]=tag[i];
col[mid]=col[mid+1]=tag[i];
sum[ls]=sum[rs]=1;
tag[i]=0;
return ;
}
void update(int l,int r,int L,int R,int x,int i){
if(L<=l&&R>=r){
sum[i]=1;
col[l]=col[r]=tag[i]=x;
return ;
}
int mid=(l+r)>>1;
push_down(i,mid);
if(L<=mid)update(l,mid,L,R,x,ls);
if(R>mid)update(mid+1,r,L,R,x,rs);
push_up(i,mid);
}
int query(int l,int r,int L,int R,int i){
if(L<=l&&R>=r){
return sum[i];
}
int mid=(l+r)>>1;
push_down(i,mid);
int ans=0;
if(L<=mid)ans+=query(l,mid,L,R,ls);
if(R>mid)ans+=query(mid+1,r,L,R,rs);
if(L<=mid&&R>mid&&col[mid]==col[mid+1])ans--;
return ans;
}
}tree;
void change(int x,int y,int k){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
tree.update(1,n,dfn[top[x]],dfn[x],k,1);
x=fa[top[x]];
}
if(dfn[x]>dfn[y])swap(x,y);
tree.update(1,n,dfn[x],dfn[y],k,1);
return ;
}
int get(int x,int y){
int u=x,v=y,ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans+=tree.query(1,n,dfn[top[x]],dfn[x],1);
x=fa[top[x]];
}
if(dfn[x]>dfn[y])swap(x,y);
ans+=tree.query(1,n,dfn[x],dfn[y],1);
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
if(col[dfn[top[u]]]==col[dfn[fa[top[u]]]])ans--;
u=fa[top[u]];
}
return ans;
}
signed main(){
cin>>n>>m;
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].pb(v);
G[v].pb(u);
}
dfs(1,0);
dfs1(1,1);
tree.build(1,n,1);
while(m--){
char op;
cin>>op;
int a,b,c;
if(op=='C'){
cin>>a>>b>>c;
change(a,b,c);
}
else{
cin>>a>>b;
cout<<get(a,b)<<endl;
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?