#include<bits/stdc++.h>
using namespace std;
#define push_back emplace_back
const int N=1e5+5;
int n,m,sum[N];
int head[N],tot;
struct Node
{
int nxt,to;
} edge[N<<1];
void add(int u,int v)
{
edge[++tot]=Node {head[u],v},head[u]=tot;
}
int fa[N],deep[N],son[N],sze[N];
void dfs1(int now,int f,int dep)
{
fa[now]=f,deep[now]=dep,sze[now]=1;
for(int i=head[now]; i; i=edge[i].nxt)
{
if(edge[i].to!=f)
{
dfs1(edge[i].to,now,dep+1),sze[now]+=sze[edge[i].to];
if(sze[son[now]]<sze[edge[i].to]) son[now]=edge[i].to;
}
}
}
int cnt,id[N],top[N],a[N];
void dfs2(int now,int ffa)
{
top[now]=ffa,id[now]=++cnt,a[cnt]=sum[now];
if(son[now]) dfs2(son[now],ffa);
for(int i=head[now]; i; i=edge[i].nxt)
if(edge[i].to!=fa[now]&&edge[i].to!=son[now])
dfs2(edge[i].to,edge[i].to);
}
struct SegmentTree
{
int l,r;
int sum,flag;
int lcolor,rcolor;
} t[N<<2];
void spread(int p)
{
if(t[p].flag)
{
t[p*2].sum=t[p*2+1].sum=1;
t[p*2].flag=t[p*2+1].flag=t[p].flag;
t[p*2].lcolor=t[p].flag,t[p*2].rcolor=t[p].flag;
t[p*2+1].lcolor=t[p*2+1].rcolor=t[p].flag;
t[p].flag=0;
}
}
SegmentTree operator+(SegmentTree a,SegmentTree b)
{
SegmentTree c;
c.l=a.l,c.r=b.r;
c.lcolor=a.lcolor,c.rcolor=b.rcolor;
c.sum=a.sum+b.sum;
if(a.rcolor==b.lcolor) c.sum--;
return c;
}
void build(int l,int r,int p)
{
t[p].l=l,t[p].r=r;
if(l==r) return (void)(t[p].sum=1,t[p].lcolor=t[p].rcolor=a[l]);
int mid=(l+r)>>1;
build(l,mid,p*2),build(mid+1,r,p*2+1);
t[p]=t[p*2]+t[p*2+1];
}
void change(int l,int r,int p,int k)
{
if(l<=t[p].l&&t[p].r<=r) return (void)(t[p].sum=1,t[p].flag=t[p].lcolor=t[p].rcolor=k);
spread(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid) change(l,r,p*2,k);
if(r>mid) change(l,r,p*2+1,k);
t[p]=t[p*2]+t[p*2+1];
}
SegmentTree ask(int l,int r,int p)
{
if(l<=t[p].l&&t[p].r<=r) return t[p];
spread(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid&&r>mid) return ask(l,r,p*2)+ask(l,r,p*2+1);
else if(l<=mid) return ask(l,r,p*2);
else if(r>mid) return ask(l,r,p*2+1);
}
void changeroad(int x,int y,int k)
{
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]]) swap(x,y);
change(id[top[x]],id[x],1,k),x=fa[top[x]];
}
if(deep[x]>deep[y]) swap(x,y);
change(id[x],id[y],1,k);
}
int askroad(int x,int y)
{
int cnt=0;
SegmentTree now;
int ans1=INT_MIN,ans2=INT_MIN;
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]]) swap(x,y),swap(ans1,ans2);
now=ask(id[top[x]],id[x],1);
cnt+=now.sum-(ans1==now.rcolor),ans1=now.lcolor;
x=fa[top[x]];
}
if(deep[x]>deep[y]) swap(x,y),swap(ans1,ans2);
now=ask(id[x],id[y],1);
cnt+=now.sum-(ans1==now.lcolor)-(ans2==now.rcolor);
return cnt;
}
signed main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1; i<=n; i++) cin>>sum[i];
for(int i=1,x,y; i<n; i++) cin>>x>>y,add(x,y),add(y,x);
dfs1(1,-1,1),dfs2(1,1),build(1,n,1);
while(m--)
{
string op;
int x,y,k;
cin>>op;
if(op=="C") cin>>x>>y>>k,changeroad(x,y,k);
else cin>>x>>y,cout<<askroad(x,y)<<'\n';
}
return 0;
}
- 我本地编译器和洛谷IDE上的答案不一样
- 为什么把 num 和 flag 的数据类型改成 long long 就会得出奇怪的答案