zoukankan      html  css  js  c++  java
  • SPOJ8791 DYNALCA LCT


    考虑(LCT)

    不难发现,我们不需要换根...

    对于操作(1)(splay(u))然后连虚边即可

    对于操作(3),我们可以先(access(u)),然后再(access(v)),然后查最后一个虚边变实边的点

    对于操作(2)

    可以选择(access(u), splay(u)),然后从(u)所在的(splay)中删去(u)

    也可以选择(access(u), access(v), splay(u)),这时,边((u, v))成为虚边,十分好删除

    复杂度(O(n log n))


    版本1:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    #define ri register int
    #define rep(io, st, ed) for(ri io = st; io <= ed; io ++)
    #define drep(io, ed, st) for(ri io = ed; io >= st; io --)
        
    #define gc getchar
    inline int read() {
        int p = 0, w = 1; char c = gc();
        while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }
        while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
        return p * w;
    }
    
    const int sid = 1e5 + 5;
    
    int n, m;
    char s[sid];
    int son[sid][2], fa[sid], pra[sid];
    
    #define ls(o) son[(o)][0]
    #define rs(o) son[(o)][1]
    
    inline bool isrc(int o) { return rs(fa[o]) == o; }
    inline bool isr(int o) { return !fa[o] || (ls(fa[o]) != o && rs(fa[o]) != o); }
    
    inline void rotate(int o) {
    	int f = fa[o], g = fa[f];
    	int ro = isrc(o), rf = isrc(f), p = son[o][ro ^ 1];
    	if(!isr(f)) son[g][rf] = o; son[o][ro ^ 1] = f; son[f][ro] = p;
    	fa[p] = f; fa[f] = o; fa[o] = g;
    }
    
    inline void splay(int o) {
    	while(!isr(o)) {
    		int f = fa[o];
    		if(!isr(f)) rotate(isrc(f) == isrc(o) ? f : o);
    		rotate(o);
    	}
    }
    
    int lca = 0;
    inline void access(int o) {
    	int lst = 0;
    	while(o) {
    		splay(o); rs(o) = lst;
    		lca = lst = o; o = fa[o];
    	}
    }
    
    int main() {
    	n = read(); m = read();
    	rep(i, 1, m) {
    		int u, v;
    		scanf("%s", s);
    		if(s[1] == 'i') {
    			u = read(); v = read();
    			splay(u); pra[u] = v; fa[u] = v;
    		}
    		else if(s[1] == 'c') {
    			u = read(); v = read();
    			access(u); access(v);
    			printf("%d
    ", lca);
    		}
    		else if(s[1] == 'u') {
    			u = read();
    			access(u); access(pra[u]);
    			splay(u); fa[u] = 0;
    		}
    	}
    	return 0;
    }
    

    版本(2)

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    #define ri register int
    #define rep(io, st, ed) for(ri io = st; io <= ed; io ++)
    #define drep(io, ed, st) for(ri io = ed; io >= st; io --)
        
    #define gc getchar
    inline int read() {
        int p = 0, w = 1; char c = gc();
        while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }
        while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
        return p * w;
    }
    
    const int sid = 1e5 + 5;
    
    int n, m;
    char s[sid];
    int son[sid][2], fa[sid], pra[sid];
    
    #define ls(o) son[(o)][0]
    #define rs(o) son[(o)][1]
    
    inline bool isrc(int o) { return rs(fa[o]) == o; }
    inline bool isr(int o) { return !fa[o] || (ls(fa[o]) != o && rs(fa[o]) != o); }
    
    inline void rotate(int o) {
        int f = fa[o], g = fa[f];
        int ro = isrc(o), rf = isrc(f), p = son[o][ro ^ 1];
        if(!isr(f)) son[g][rf] = o; son[o][ro ^ 1] = f; son[f][ro] = p;
        fa[p] = f; fa[f] = o; fa[o] = g;
    }
    
    inline void splay(int o) {
        while(!isr(o)) {
            int f = fa[o];
            if(!isr(f)) rotate(isrc(f) == isrc(o) ? f : o);
            rotate(o);
        }
    }
    
    int lca = 0;
    inline void access(int o) {
        int lst = 0;
        while(o) {
            splay(o); rs(o) = lst;
            lca = lst = o; o = fa[o];
        }
    }
    
    int main() {
        n = read(); m = read();
        rep(i, 1, m) {
            int u, v;
            scanf("%s", s);
            if(s[1] == 'i') {
                u = read(); v = read();
                splay(u); pra[u] = v; fa[u] = v;
            }
            else if(s[1] == 'c') {
                u = read(); v = read();
                access(u); access(v);
                printf("%d
    ", lca);
            }
            else if(s[1] == 'u') {
                u = read();
                access(u); splay(u);
                ls(u) = fa[ls(u)] = 0;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    falsk-web 表单
    falsk-web 表单
    falsk-web 表单
    falsk-web 表单
    治理“假货之都”需要大数据打假
    治理“假货之都”需要大数据打假
    治理“假货之都”需要大数据打假
    治理“假货之都”需要大数据打假
    与好友合伙创业,他开店4家,月销售额已超过30万元
    放弃优越的都市生活,他返乡创业带动家乡人民共同致富
  • 原文地址:https://www.cnblogs.com/reverymoon/p/10091974.html
Copyright © 2011-2022 走看看