• UOJ #274. 【清华集训2016】温暖会指引我们前行 [lct]


    #274. 【清华集训2016】温暖会指引我们前行

    题意比较巧妙

    裸lct维护最大生成树

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    #define lc t[x].ch[0]
    #define rc t[x].ch[1]
    #define pa t[x].fa
    const int N = 4e5+5, INF = 1e9+5;
    inline int read(){
    	char c=getchar(); int x=0,f=1;
    	while(c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
    	while(c>='0' && c<='9') {x=x*10+c-'0'; c=getchar();}
    	return x*f;
    }
    
    int n, m, val[N], id, u, v, tem, w;
    struct edge{int u, v;} e[N];
    char s[10];
    
    namespace lct {
    	struct meow{ int ch[2], fa, rev, sum, w, p; } t[N];
    	inline int wh(int x) {return t[pa].ch[1] == x;}
    	inline bool isr(int x) {return t[pa].ch[0] != x && t[pa].ch[1] != x;}
    	inline void rever(int x) {t[x].rev ^= 1; swap(lc, rc);}
    	inline void pushdn(int x) {
    		if(t[x].rev) {
    			if(lc) rever(lc);
    			if(rc) rever(rc);
    			t[x].rev = 0;
    		}
    	}
    	inline void pd(int x) {if(!isr(x)) pd(pa); pushdn(x);}
    	inline void update(int x) {
    		t[x].sum = t[lc].sum + t[rc].sum + t[x].w;
    		t[x].p = x;
    		if(lc && val[ t[lc].p ] < val[ t[x].p ]) t[x].p = t[lc].p;
    		if(rc && val[ t[rc].p ] < val[ t[x].p ]) t[x].p = t[rc].p;
    	}
    	inline void rotate(int x) {
    		int f = t[x].fa, g = t[f].fa, c = wh(x);
    		if(!isr(f)) t[g].ch[wh(f)] = x; t[x].fa = g;
    		t[f].ch[c] = t[x].ch[c^1]; t[ t[f].ch[c] ].fa = f;
    		t[x].ch[c^1] = f; t[f].fa = x;
    		update(f); update(x);
    	}
    	inline void splay(int x) {
    		pd(x);
    		for(; !isr(x); rotate(x))
    			if(!isr(pa)) rotate(wh(x) == wh(pa) ? pa : x);
    	}
    	inline void access(int x) {
    		for(int y=0; x; y=x, x=pa)
    			splay(x), rc=y, update(x);
    	}
    	inline void maker(int x) { access(x); splay(x); rever(x);}
    	inline void link(int x, int y) { maker(x); t[x].fa = y; }
    	inline void cut(int x, int y) { 
    		maker(x); access(y); splay(y); 
    		t[x].fa = t[y].ch[0] = 0; update(y); 
    	}
    	inline void split(int x, int y) { maker(x), access(y); splay(y); }
    } using namespace lct;
    
    int fa[N];
    inline int find(int x) {return x == fa[x] ? x : fa[x] = find(fa[x]);}
    inline void add() {
    	id=read()+1+n, u=read()+1, v=read()+1, tem=read(), w=read(); //printf("
    add %d  %d--%d  %d  %d
    ", id, u, v, tem, w);
    	e[id] = (edge){u, v};
    	val[id] = tem;
    	t[id].sum = t[id].w = w; t[id].p = id;
    	if(find(u) != find(v)) { 
    		fa[find(u)] = find(v);
    		link(id, u); link(id, v);
    	} else {
    		split(u, v);
    		int a = t[v].p; //printf("aaa %d
    ", a);
    		if(val[a] < val[id]) { 
    			cut(a, e[a].u); cut(a, e[a].v);
    			link(id, u); link(id, v);
    		}
    	}
    }
    inline void que(int u, int v) {
    	if(find(u) != find(v)) puts("-1");
    	else split(u, v), printf("%d
    ", t[v].sum);
    }
    inline void cha(int id, int w) { //printf("
    cha %d  %d
    ", id, w);
    	t[id].w = w; splay(id);
    }
    int main() {
    	freopen("in", "r", stdin);
    	n=read(); m=read();
    	for(int i=1; i<=n; i++) fa[i] = i, val[i] = INF;
    	for(int i=1; i<=m; i++) { //printf("
    Q %d
    ", i);
    		scanf("%s", s);
    		if(s[0] == 'f') add();
    		if(s[0] == 'm') u=read()+1, v=read()+1, que(u, v);
    		if(s[0] == 'c') id=read()+1+n, w=read(), cha(id, w);
    	}
    }
    
    
  • 相关阅读:
    关于Java的i++和++i的区别
    Java基础(八 前面补充)
    Java基础(七)
    Java基础(六)
    Java基础(五)
    Java基础(四)
    Java基础(三)
    Java基础(二)
    Java基础
    阿里技术专员《并发编程技术分享》
  • 原文地址:https://www.cnblogs.com/candy99/p/6725106.html
Copyright © 2020-2023  润新知