zoukankan      html  css  js  c++  java
  • 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
    ",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;
    }
  • 相关阅读:
    POJ 3211 Washing Clothes
    MySQL 优化Limit分页
    signed 与 unsigned 有符号和无符号数
    C/C++ 变量的初始化
    C/C++ 变量的初始化
    返回值的判断
    返回值的判断
    《涅槃经》的研读
    《涅槃经》的研读
    Opencv Surf算子特征提取与最优匹配
  • 原文地址:https://www.cnblogs.com/invoid/p/5372730.html
Copyright © 2011-2022 走看看