bzoj2243: [SDOI2011]染色

我抄的,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\n",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\n",lct.Query(a,b));
        }
    }
    return 0;
}
posted @ 2016-04-09 21:34  invoid  阅读(153)  评论(0编辑  收藏  举报