我抄的,lct。 转疯了。。 先建图保存父节点。剩下我也看不懂。。。先留个坑日后再补吧//能补上。。?。。。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 100000 + 10; char op[10]; int a,b,c,n,m; struct Edge { int to,next; } edges[maxn*2]; struct LCT { int l[maxn],r[maxn],h[maxn],f[maxn]; // f: father int c[maxn],cl[maxn],cr[maxn],cnt[maxn],s[maxn],COLOR[maxn]; bool Swap[maxn],root[maxn]; int p; void color(int x,int C) { if(!x) return; c[x] = cl[x] = cr[x] = COLOR[x] = C; cnt[x] = 1; } void swap1(int x) { if(!x) return; swap(l[x],r[x]); swap(cl[x],cr[x]); Swap[x] ^= 1; } void push(int x) { if(COLOR[x] != -1) { color(l[x],COLOR[x]); color(r[x],COLOR[x]); COLOR[x] = -1; } if(Swap[x]) { swap1(l[x]); swap1(r[x]); Swap[x] = 0; } } void push_link(int x) { if(!root[x]) push_link(f[x]); push(x); } void update(int x) { s[x] = s[l[x]] + s[r[x]] + 1; cl[x] = (l[x]?cl[l[x]]:c[x]); cr[x] = (r[x]?cr[r[x]]:c[x]); cnt[x] = 1; if(l[x]) cnt[x] += cnt[l[x]] - (cr[l[x]] == c[x]); if(r[x]) cnt[x] += cnt[r[x]] - (cl[r[x]] == c[x]); //printf("cnt[%d] = %d ",x,cnt[x]); } void lr(int x) { int y = f[x]; r[y] = l[x]; if(l[x]) f[l[x]] = y; f[x] = f[y]; if(root[y]) { root[y] = 0; root[x] = 1; } else if(l[f[y]] == y) l[f[y]] = x; else r[f[y]] = x; f[y] = x; l[x] = y; update(y); update(x); } void rr(int x) { int y = f[x]; l[y] = r[x]; if(r[x]) f[r[x]] = y; f[x] = f[y]; if(root[y]) { root[y] = 0; root[x] = 1; } else if(l[f[y]] == y) l[f[y]] = x; else r[f[y]] = x; f[y] = x; r[x] = y; update(y); update(x); } void rotate(int x) { if(l[f[x]] == x) rr(x); else lr(x); } void splay(int x) { push_link(x); while(!root[x]) { if(root[f[x]]) rotate(x); else if((l[f[x]] == x) == (l[f[f[x]]] == f[x])) { rotate(f[x]); rotate(x); } else { rotate(x); rotate(x); } } } int access(int x) { int y; for(y = 0; x; x = f[y = x]) { splay(x); root[r[x]] = 1; r[x] = y; root[r[x]] = 0; update(x); } return y; } void Color(int a,int b,int c) { access(a); splay(a); swap1(a); access(b); splay(b); color(b,c); } int Query(int a,int b) { access(a); splay(a); swap1(a); access(b); splay(b); return cnt[b]; } void add(int u,int v) { edges[++p].to = v; edges[p].next = h[u]; h[u] = p; edges[++p].to = u; edges[p].next = h[v]; h[v] = p; } void dfs(int u) { for(int i = h[u]; ~i; i = edges[i].next) if(edges[i].to != f[u]) { f[edges[i].to] = u; dfs(edges[i].to); } } void build() { for(int i = 1; i <= n; i++) { COLOR[i] = -1; Swap[i] = 0; s[i] = root[i] = cnt[i] = 1; } for(int i = 1; i <= n; i++) { scanf("%d",&c[i]); cl[i] = cr[i] = c[i]; } memset(h,-1,sizeof(h)); for(int i = 1,a,b; i < n; i++) { scanf("%d%d",&a,&b); add(a,b); } dfs(1); } } lct; int main() { scanf("%d%d",&n,&m); lct.build(); while(m--) { scanf("%s",op); if(op[0] == 'C') { scanf("%d%d%d",&a,&b,&c); lct.Color(a,b,c); } else { scanf("%d%d",&a,&b); printf("%d ",lct.Query(a,b)); } } return 0; }