15分,三个点AC了,其它基本全部RE。。。
珂朵莉树+树剖
#include<bits/stdc++.h>
#define ll long long
#define un unsigned
#define pb push_back
#define mp make_pair
using namespace std;
template<typename T> inline void read(T &x){
x=0;char c=getchar();bool flag=false;
while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
if(flag)x=-x;
}
template<typename T> inline void write(T x){
short st[30],tp=0;
if(x<0) putchar('-'),x=-x;
do st[++tp]=x%10,x/=10; while(x);
while(tp) putchar('0'|st[tp--]);
}
#define wr write
#define rd read
#define pk putchar(' ')
#define ed puts("")
#define it set<node>::iterator
const int maxn=1e5+10;
struct node{
int l,r;
mutable ll v;
node(int L,int R=-1,int V=0):l(L),r(R),v(V) {}
bool operator < (const node &px)const{
return l<px.l;
}
};
set<node>s;
it split(int pos){
it p=s.lower_bound(node(pos));
if(p!=s.end()&&p->l==pos) return p;
--p;
int L=p->l,R=p->r;
ll V=p->v;
s.erase(p);
s.insert(node(L,pos-1,V));
return s.insert(node(pos,R,V)).first;
}
void assign(int l,int r,ll V=0){
it pl=split(l),pr=split(r+1);
s.erase(pl,pr);
s.insert(node(l,r,V));
}
struct edge{
int nxt,to;
}e[2*maxn];
int fa[maxn],deep[maxn],size[maxn],top[maxn],son[maxn],cnt,inde,dfc[maxn],head[maxn],b[maxn],a[maxn];
inline void add(int u,int v){
e[++cnt].to=v;
e[cnt].nxt=head[u];
head[u]=cnt;
}
inline void dfs1(int x,int fat){
size[x]=1;
fa[x]=fat;
son[x]=0;
size[0]=0;
for(int i=head[x];i;i=e[i].nxt){
int y=e[i].to;
if(y==fat) continue;
deep[y]=deep[x]+1;
dfs1(y,x);
size[x]+=size[y];
if(size[y]>size[son[x]]) son[x]=y;
}
}
inline void dfs2(int x,int fat,int t){
dfc[x]=++inde;
a[inde]=b[x];
top[x]=t;
if(!son[x]) return;
dfs2(son[x],x,t);
for(int i=head[x];i;i=e[i].nxt){
int y=e[i].to;
if(y==fat||y==son[x]) continue;
dfs2(y,x,y);
}
}
inline void edge_assign(int x,int y,int v){
while(top[x]!=top[y]){
if(deep[top[x]]<deep[top[y]]) swap(x,y);
assign(dfc[top[x]],dfc[x],v);
x=fa[top[x]];
}
if(deep[x]>deep[y]) swap(x,y);
assign(dfc[x],dfc[y],v);
}
inline int edge_query(int x,int y){
int ans=0,last1=0,last2=0;
it itl,itr;
while(top[x]!=top[y]){
if(deep[top[x]]>deep[top[y]]){
itr=split(dfc[x]+1),itl=split(dfc[top[x]]);
for(--itr;;--itr){
if(itr->v!=last1) last1=itr->v,++ans;
if(itr==itl) break;
}
x=fa[top[x]];
}
else{
itr=split(dfc[y]+1),itl=split(dfc[top[y]]);
for(--itr;;--itr){
if(itr->v!=last2) last2=itr->v,++ans;
if(itr==itl) break;
}
y=fa[top[y]];
}
}
if(deep[x]>deep[y]){
itr=split(dfc[x]+1),itl=split(dfc[y]);
for(--itr;;--itr){
if(itr->v!=last1) last1=itr->v,++ans;
if(itr==itl) break;
}
x=fa[top[x]];
}
else{
itr=split(dfc[y]+1),itl=split(dfc[x]);
for(--itr;;--itr){
if(itr->v!=last2) last2=itr->v,++ans;
if(itr==itl) break;
}
y=fa[top[y]];
}
return ans-(last1==last2);
}
signed main(){
int q,n,i,x,y,v;
rd(n),rd(q);
char opt;
for(i=1;i<=n;i++) rd(b[i]);
for(i=1;i<n;i++){
rd(x),rd(y);
add(x,y);
add(y,x);
}
dfs1(1,0);
dfs2(1,0,1);
for(i=1;i<=n;i++) s.insert(node(i,i,a[i]));
//for(i=1;i<=n;i++) wr(a[i]),pk;
//ed;
while(q--){
cin>>opt>>x>>y;
if(opt=='C'){
cin>>v;
edge_assign(x,y,v);
}
else{
wr(edge_query(x,y)),ed;
}
}
}
求调