先知道是树剖后一下子就想出来了。。。。。。应该不难的,但是代码写得有点长,调了好久。。。。。。。
还要感谢段大神帮我调出来了^-^是query写错了,在fu == fv的时候,没有处理好标记QAQ
here is my program
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define lc (o<<1)
#define rc (o<<1|1)
#define pb push_back
#define For(i, a, b) for(int i = (a); i <= (int)(b); i++)
#define MAXN (100000+5)
int n, ql, qr, dfsn, cp;
int rco[MAXN], fa[MAXN], siz[MAXN], top[MAXN], son[MAXN], dep[MAXN], w[MAXN], co[MAXN];
vector<int> G[MAXN];
struct node{
int st, en, cnt;
node(){
st = en = cnt = 0;
}
node operator +(const node &rhs)const{
if(!rhs.st && !rhs.en && !rhs.cnt) return *this;
if(!st && !en && !cnt) return rhs;
node ret;
ret.cnt = cnt+rhs.cnt;
if(en == rhs.st) ret.cnt--;
ret.st = st; ret.en = rhs.en;
return ret;
}
void print(){
printf("%d %d %d\n", st, en, cnt);
}
};
struct Seg_tree{
node inf[MAXN*4];
int bj[MAXN*4];
inline void pushdown(int o){
if(!bj[o]) return;
bj[o] = false; bj[lc] = bj[rc] = true;
inf[lc].st = inf[rc].st = inf[lc].en = inf[rc].en = inf[o].st;
inf[lc].cnt = inf[rc].cnt = inf[o].cnt;
}
inline void maintain(int o){
inf[o] = inf[lc]+inf[rc];
}
inline void build(int o, int L, int R){
if(L == R){
++cp;
inf[o].st = inf[o].en = rco[cp]; inf[o].cnt = 1;
return;
}
int mid = (L+R)>>1;
build(lc, L, mid); build(rc, mid+1, R);
maintain(o);
}
inline void modify(int o, int L, int R, int col){
if(ql <= L && qr >= R){
inf[o].st = inf[o].en = col; inf[o].cnt = 1; bj[o] = true;
return;
}
pushdown(o);
int mid = (L+R)>>1;
if(ql <= mid) modify(lc, L, mid, col);
if(qr > mid) modify(rc, mid+1, R, col);
maintain(o);
}
inline node query(int o, int L, int R){
if(ql <= L && qr >= R) return inf[o];
pushdown(o);
int mid = (L+R)>>1;
if(qr <= mid) return query(lc, L, mid);
else if(ql > mid) return query(rc, mid+1, R);
else return query(lc, L, mid)+query(rc, mid+1, R);
}
}ST;
void dfs1(int now, int La, int D){
fa[now] = La; siz[now] = 1; dep[now] = D;
int maxw = 0;
For(i, 0, G[now].size()-1){
int v = G[now][i];
if(v == La) continue;
dfs1(v, now, D+1);
siz[now] += siz[v];
if(siz[v] > maxw) maxw = siz[v], son[now] = v;
}
}
void dfs2(int now, int Top){
top[now] = Top; w[now] = ++dfsn;
int v;
if(son[now]) dfs2(son[now], Top);
For(i, 0, G[now].size()-1){
v = G[now][i];
if(v == son[now] || v == fa[now]) continue;
dfs2(v, v);
}
}
void update(int u, int v, int col){
while(u != v){
int fu = top[u], fv = top[v];
if(dep[fu] < dep[fv]){
swap(u, v); swap(fu, fv);
}
if(fu == fv){
ql = min(w[u], w[v]); qr = w[u]+w[v]-ql;
ST.modify(1, 1, n, col);
break;
}
ql = w[fu]; qr = w[u];
ST.modify(1, 1, n, col);
u = fa[fu];
}
if(u == v){
ql = qr = w[u];
ST.modify(1, 1, n, col);
}
}
void query(int u, int v){
node tu, tv;
while(u != v){
int fu = top[u], fv = top[v];
if(dep[fu] < dep[fv]){
swap(u, v); swap(fu, fv); swap(tu, tv);
}
if(fu == fv){
ql = min(w[u], w[v]); qr = w[u]+w[v]-ql;
if(ql == w[u]) tv = ST.query(1, 1, n)+tv;
else tu = ST.query(1, 1, n)+tu;
break;
}
ql = w[fu]; qr = w[u];
tu = ST.query(1, 1, n)+tu;
u = fa[fu];
}
if(u == v){
ql = qr = w[u];
tu = ST.query(1, 1, n)+tu;
}
int ans = tu.cnt+tv.cnt;
if(tu.st == tv.st) ans--;
printf("%d\n", ans);
}
int main(){
int m;
scanf("%d%d", &n, &m);
For(i, 1, n) scanf("%d", &co[i]);
For(i, 1, n-1){
int x, y;
scanf("%d%d", &x, &y);
G[x].pb(y); G[y].pb(x);
}
dfs1(1, 0, 1); dfs2(1, 1);
For(i, 1, n) rco[w[i]] = co[i];
ST.build(1, 1, n);
char s[5];
int a, b, c;
while(m--){
scanf("%s", s);
if(s[0] == 'C'){
scanf("%d%d%d", &a, &b, &c);
update(a, b, c);
}else{
scanf("%d%d", &a, &b);
if(a != b) query(a, b);
else printf("1\n");
}
}
return 0;
}