• 总结-LCT


    题单: https://www.zybuluo.com/xzyxzy/note/1027479

    LuoguP3203 [HNOI2010]弹飞绵羊

    动态加边,删边

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #define R(a,b,c) for(register int a = (b); (a) <= (c); ++(a))
    #define nR(a,b,c) for(register int a = (b); (a) >= (c); --(a))
    #define Fill(a,b) memset(a, b, sizeof(a))
    #define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
    #define ll long long
    #define u32 unsigned int
    #define u64 unsigned long long
     
    //#define ON_DEBUGG
     
    #ifdef ON_DEBUGG
     
    #define D_e_Line printf("
    ----------
    ")
    #define D_e(x) cout << (#x) << " : " << x << endl
    #define Pause() system("pause")
    #define FileOpen() freopen("in.txt", "r", stdin)
    #define FileSave() freopen("out.txt", "w", stdout)
    #include <ctime>
    #define TIME() fprintf(stderr, "
    time: %.3fms
    ", clock() * 1000.0 / CLOCKS_PER_SEC)
    
    #else
     
    #define D_e_Line ;
    #define D_e(x) ;
    #define Pause() ;
    #define FileOpen() ;
    #define FileSave() ;
    #define TIME() ;
    //char buf[1 << 21], *p1 = buf, *p2 = buf;
    //#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
     
    #endif
     
    using namespace std;
    struct ios{
        template<typename ATP>inline ios& operator >> (ATP &x){
            x = 0; int f = 1; char ch;
            for(ch = getchar(); ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
            while(ch >= '0' && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar();
            x *= f;
            return *this;
        }
    }io;
     
    template<typename ATP>inline ATP Max(ATP a, ATP b){
        return a > b ? a : b;
    }
    template<typename ATP>inline ATP Min(ATP a, ATP b){
        return a < b ? a : b;
    }
    template<typename ATP>inline ATP Abs(ATP a){
        return a < 0 ? -a : a;
    }
    
    const int N = 200007;
    
    int n;
    int val[N];
    
    struct Tree{
    	int ch[2], fa, val, siz;
    	bool rev;
    }t[N];
    #define ls t[u].ch[0]
    #define rs t[u].ch[1]
    #define root (n + 1)
    
    inline bool Ident(int u) {
    	return u == t[t[u].fa].ch[1];
    }
    
    inline bool IsRoot(int u) {
    	return t[t[u].fa].ch[0] != u && t[t[u].fa].ch[1] != u;
    }
    
    inline void Pushup(int u) {
    	t[u].siz = t[ls].siz + t[rs].siz + 1;
    }
    
    inline void Pushrev(int u) {
    	Swap(ls, rs);
    	t[u].rev ^= 1;
    }
    
    inline void Pushdown(int u) {
    	if(!t[u].rev) return;
    	if(ls) Pushrev(ls);
    	if(rs) Pushrev(rs);
    	t[u].rev = 0;
    }
    
    int sta[N], top;
    
    inline void Rotate(int x) {
    	int y = t[x].fa, z = t[y].fa, k = Ident(x);
    	t[x].fa = z; if(!IsRoot(y)) t[z].ch[Ident(y)] = x;
    	t[y].ch[k] = t[x].ch[k ^ 1], t[t[x].ch[k ^ 1]].fa = y;
    	t[x].ch[k ^ 1] = y, t[y].fa = x;
    	Pushup(y), Pushup(x);
    }
    
    inline void Splay(int u){
    	int x = u;
    	while(!IsRoot(u)){
    		sta[++top] = u;
    		u = t[u].fa;
    	}
    	sta[++top] = u;
    	while(top) Pushdown(sta[top--]);
    	while(!IsRoot(x)) {
    		int y = t[x].fa;
    		if(!IsRoot(y)){
    			Ident(x) == Ident(y) ? Rotate(y) : Rotate(x);
    		}
    		Rotate(x);
    	}
    	Pushup(x);
    }
    
    inline void Access(int u) {
    	for(register int v = 0; u; v = u, u = t[u].fa){
    	 	Splay(u);
    	 	t[u].ch[1] = v;
    	 	Pushup(u);
    	}
    }
    
    inline void MakeRoot(int u) {
    	Access(u);
    	Splay(u);
    	Pushrev(u);
    }
    
    inline int FindRoot(int u) {
    	Access(u);
    	Splay(u);
    	while(ls) u = ls;
    	Splay(u);
    	return u;
    }
    
    inline void Split(int u, int v) {
    	MakeRoot(u);
    	Access(v);
    	Splay(v);
    }
    
    inline void Link(int u, int v) {
    	Split(u, v);
    	t[u].fa = v;
    }
    
    inline void Cut(int u, int v) {
    	MakeRoot(u);
    	if(FindRoot(v) == u && t[v].fa == u && !t[v].ch[0]){
    		t[v].fa = t[u].ch[1] = 0;
    		Pushup(u);
    	}
    }
    
    inline void Modify(int u, int w) {
    //	Access(u); // no access
    	Splay(u);
    	t[u].val = w;
    	Pushup(u);
    }
    
    inline int Query(int u) {
    	MakeRoot(u);
    	Access(root);
    	Splay(root);
    	return t[root].siz - 1;
    }
    
    int main(){
    FileOpen();
    FileSave();
    	int m;
    	io >> n;
    	R(i,1,n){
    		io >> val[i];
    		if(i + val[i] <= n)
    			Link(i, i + val[i]);
    		else
    			Link(i, root);
    	}
    	
    	io >> m;
    	
    	while(m--){
    		int opt;
    		io >> opt;
    		if(opt == 1){
    			int x;
    			io >> x;
    			++x; 
    			printf("%d
    ", Query(x));
    		}
    		else{
    			int x, w;
    			io >> x >> w;
    			++x;
    			Cut(x, x + val[x] <= n ? x + val[x] : root);
    			Modify(x, w);
    			Link(x, x + w <= n ? x + w : root);
    			val[x] = w;
    		}
    	}
    	TIME();
    	return 0;
    } 
    

    LuoguP2387 [NOI2014]魔法森林

    边权拆点两端,一维偏序排序,二维偏序类似(Kruskal)

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #define R(a,b,c) for(register int a = (b); (a) <= (c); ++(a))
    #define nR(a,b,c) for(register int a = (b); (a) >= (c); --(a))
    #define Fill(a,b) memset(a, b, sizeof(a))
    #define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
    #define ll long long
    #define u32 unsigned int
    #define u64 unsigned long long
     
    #define ON_DEBUGG
     
    #ifdef ON_DEBUGG
     
    #define D_e_Line printf("
    ----------
    ")
    #define D_e(x) cout << (#x) << " : " << x << endl
    #define Pause() system("pause")
    #define FileOpen() freopen("in.txt", "r", stdin)
    #define FileSave() freopen("out.txt", "w", stdout)
    #include <ctime>
    #define TIME() fprintf(stderr, "
    time: %.3fms
    ", clock() * 1000.0 / CLOCKS_PER_SEC)
    
    #else
     
    #define D_e_Line ;
    #define D_e(x) ;
    #define Pause() ;
    #define FileOpen() ;
    #define FileSave() ;
    #define TIME() ;
    //char buf[1 << 21], *p1 = buf, *p2 = buf;
    //#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
     
    #endif
     
    using namespace std;
    struct ios{
        template<typename ATP>inline ios& operator >> (ATP &x){
            x = 0; int f = 1; char ch;
            for(ch = getchar(); ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
            while(ch >= '0' && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar();
            x *= f;
            return *this;
        }
    }io;
     
    template<typename ATP>inline ATP Max(ATP a, ATP b){
        return a > b ? a : b;
    }
    template<typename ATP>inline ATP Min(ATP a, ATP b){
        return a < b ? a : b;
    }
    template<typename ATP>inline ATP Abs(ATP a){
        return a < 0 ? -a : a;
    }
    
    const int N = 5e4 + 7;
    const int M = 1e5 + 7;
    
    struct Node{
    	int x, y, valA, valB;
    	bool operator < (const Node &com) const{
    		if(valA != com.valA) return valA < com.valA;
    		return valB < com.valB;
    	}
    }a[M];
    
    int fa[N];
    inline int Find(int x) {
    	return x == fa[x] ? x : fa[x] = Find(fa[x]);
    }
    
    struct Tree{
    	int ch[2], fa, val, mx; // mx : maxPos
    	bool rev;
    }t[N * 3];
    
    #define ls t[u].ch[0]
    #define rs t[u].ch[1]
    
    inline int Ident(int u) {
    	return t[t[u].fa].ch[1] == u;
    }
    
    inline bool IsRoot(int u) {
    	return t[t[u].fa].ch[0] != u && t[t[u].fa].ch[1] != u;
    }
    
    inline void Pushup(int u) {
    	t[u].mx = u;
    	if(ls && t[t[ls].mx].val > t[t[u].mx].val) t[u].mx = t[ls].mx;
    	if(rs && t[t[rs].mx].val > t[t[u].mx].val) t[u].mx = t[rs].mx;
    }
    
    inline void Pushrev(int u) {
    	Swap(ls, rs);
    	t[u].rev ^= 1;
    }
    
    inline void Pushdown(int u) {
    	if(!t[u].rev) return;
    	if(ls) Pushrev(ls);
    	if(rs) Pushrev(rs);
    	t[u].rev = 0;
    }
    
    inline void Rotate(int x) {
    	int y = t[x].fa, z = t[y].fa, k = Ident(x);
    	t[x].fa = z; if(!IsRoot(y)) t[z].ch[Ident(y)] = x;
    	t[y].ch[k] = t[x].ch[k ^ 1], t[t[x].ch[k ^ 1]].fa = y;
    	t[x].ch[k ^ 1] = y, t[y].fa = x;
    	Pushup(y), Pushup(x);
    }
    
    int sta[N], top;
    
    inline void Splay(int u) {
    	int x = u;
    	while(!IsRoot(u)){
    		sta[++top] = u;
    		u = t[u].fa; //
    	}
    	sta[++top] = u;
    	while(top) Pushdown(sta[top--]);
    	while(!IsRoot(x)){
    		int y = t[x].fa;
    		if(!IsRoot(y)){
    			Ident(x) == Ident(y) ? Rotate(y) : Rotate(x);
    		}
    		Rotate(x);
    	}
    	Pushup(x);
    }
    
    inline void Access(int u) {
    	for(register int v = 0; u; v = u, u = t[u].fa){ //
    		Splay(u);
    		t[u].ch[1] = v;
    		Pushup(u);
    	}
    }
    
    inline void MakeRoot(int u) {
    	Access(u);
    	Splay(u);
    	Pushrev(u);
    }
    
    inline void Split(int u, int v) {
    	MakeRoot(u);
    	Access(v);
    	Splay(v);
    }
    
    inline void Link(int u, int v) {
    	Split(u, v);
    	t[u].fa = v;
    }
    
    inline void Cut(int u, int v) {
    	Split(u, v);
    	t[u].fa = t[v].ch[1] = 0;
    	Pushup(v);
    }
    
    int main() {
    	int n, m;
    	io >> n >> m;
    	int tot = 0;
    	R(i,1,m){
    		int u, v, A, B;
    		io >> u >> v >> A >> B;
    		if(u == v) continue;
    		a[++tot] = (Node){ u, v, A, B};
    	}
    	
    	m = tot;
    	sort(a + 1, a + m + 1);
    	
    	R(i,1,n) fa[i] = i; //
    	R(i,n,n + m) t[i].val = a[i - n].valB;
    
    	int ans = 0x7fffffff;
    	
    	R(i,1,m){
    		
    		int u = a[i].x, v = a[i].y;
    		int p = Find(u), q = Find(v);
    		if(p == q){
    			Split(u, v);
    			int j = t[v].mx - n;
    			if(a[j].valB <= a[i].valB) continue;
    			Cut(a[j].x, j + n), Cut(a[j].y, j + n);
    			Link(u, i + n), Link(v, i + n);
    		}
    		else{
    			fa[p] = q;
    			Link(u, i + n), Link(v, i + n);
    		}
    		if(Find(1) == Find(n)){
    			Split(1, n);
    			int j = t[n].mx - n;
    			ans = Min(ans, a[i].valA + a[j].valB);
    		}
    	}
    	
    	printf("%d", ans == 0x7fffffff ? -1 : ans);
    	
    	return 0;
    } 
    

    LuoguP4234 最小差值生成树

    “亲爱的边,你喜欢LCT维护吗”
    “不喜欢呀”
    “那你就tmd给我变成点吧”
    “呜呜呜”
    “排了你,从小往大单调着走”
    “嘤嘤嘤”
    “然后就是最小生成树,LCT版本的呢”

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #define R(a,b,c) for(register int a = (b); a <= (c); ++a)
    #define nR(a,b,c) for(register int a = (b); a >= (c); --a)
    #define Fill(a,b) memset(a, b, sizeof(a))
    #define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
    
    #define ON_DEBUGG
    
    #ifdef ON_DEBUGG
    
    #define D_e_Line printf("
    -----------
    ")
    #define D_e(x) std::cout << (#x) << " : " <<x << "
    "
    #define FileOpen() freopen("in.txt", "r", stdin)
    #define FileSave() freopen("out.txt", "w", stdout)
    #define Pause() system("pause")
    #include <ctime>
    #define TIME() fprintf(stderr, "
    TIME : %.3lfms
    ", clock() * 1000.0 / CLOCKS_PER_SEC)
    
    #else
    
    #define D_e_Line ;
    #define D_e(x) ;
    #define FileOpen() ;
    #define FilSave ;
    #define Pause() ;
    #define TIME() ;
    
    #endif
    
    struct ios {
    	template<typename ATP> ios& operator >> (ATP &x) {
    		x = 0; int f = 1; char c;
    		for(c = getchar(); c < '0' || c > '9'; c = getchar()) if(c == '-') f = -1;
    		while(c >= '0' && c <= '9') x = x * 10 + (c ^ '0'), c = getchar();
    		x *= f;
    		return *this;
    	}
    }io;
    
    using namespace std;
    
    template<typename ATP> inline ATP Min(ATP a, ATP b) {
    	return a < b ? a : b;
    }
    template<typename ATP> inline ATP Max(ATP a, ATP b) {
    	return a > b ? a : b;
    }
    template<typename ATP> inline ATP Abs(ATP a) {
    	return a < 0 ? -a : a;
    }
    
    const int N = 250007;
    
    int n;
    
    struct E {
    	int x, y, w;
    	bool operator < (const E &com) const {
    		return w < com.w;
    	}
    } e[N];
    
    struct Tree {
    	int ch[2], fa, id;
    	bool rev;
    } t[N];
    #define ls t[u].ch[0]
    #define rs t[u].ch[1]
    
    inline int Ident(int u) {
    	return t[t[u].fa].ch[1] == u;
    }
    
    inline bool IsRoot(int u) {
    	return t[t[u].fa].ch[1] != u && t[t[u].fa].ch[0] != u;
    }
    
    inline void Pushup(int u) {
    	t[u].id = u;
        if(t[ls].id > n && (t[u].id <= n || t[u].id > t[ls].id)) t[u].id = t[ls].id;
        if(t[rs].id > n && (t[u].id <= n || t[u].id > t[rs].id)) t[u].id = t[rs].id;
    }
    
    inline void Pushrev(int u) {
    	Swap(ls, rs);
    	t[u].rev ^= 1;
    }
    
    inline void Pushdown(int u) {
    	if(!t[u].rev) return;
    	if(ls) Pushrev(ls);
    	if(rs) Pushrev(rs);
    	t[u].rev = 0;
    }
    
    inline void Rotate(int x) {
    	int y = t[x].fa, z = t[y].fa, k = Ident(x);
    	t[x].fa = z; if(!IsRoot(y)) t[z].ch[Ident(y)] = x;
    	t[y].ch[k] = t[x].ch[k ^ 1], t[t[x].ch[k ^ 1]].fa = y;
    	t[x].ch[k ^ 1] = y, t[y].fa = x;
    	Pushup(y), Pushup(x);
    }
    
    int sta[N], top;
    
    inline void Splay(int u) {
    	int x = u;
    	while(!IsRoot(u)){ //
    		sta[++top] = u;
    		u = t[u].fa;
    	}
    	sta[++top] = u;
    	while(top) Pushdown(sta[top--]);
    	while(!IsRoot(x)){
    		int y = t[x].fa;
    		if(!IsRoot(y)){
    			Ident(x) == Ident(y) ? Rotate(y) : Rotate(x);
    		}
    		Rotate(x);
    	}
    	Pushup(x);
    }
    
    inline void Access(int u) {
    	for(register int v = 0; u; v = u, u = t[u].fa){
    		Splay(u);
    		t[u].ch[1] = v;
    		Pushup(u);
    	}
    }
    
    inline void MakeRoot(int u) {
    	Access(u);
    	Splay(u);
    	Pushrev(u);
    }
    
    inline int FindRoot(int u) {
    	Access(u);
    	Splay(u);
    	while(ls) u = ls;
    	Splay(u);
    	return u;
    }
    
    inline void Split(int u, int v) {
    	MakeRoot(u);
    	Access(v);
    	Splay(v);
    }
    
    inline void Link(int u, int v) {
    	Split(u, v);
    	t[u].fa = v;
    }
    
    inline bool Check(int x, int y) {
    	MakeRoot(x);
    	return FindRoot(y) != x;
    }
    
    int vis[N];
    int main() {
    	int m;
    	io >> n >> m;
    	int idx = n, ans = 0x7fffffff;
    	
    	R(i,1,m){
    		io >> e[i].x >> e[i].y >> e[i].w;
    	}
    	
    	sort(e + 1, e + m + 1);
    	
    	int tot = 1, l = 1;
    	R(i,1,m){
    		++idx;
    		int x = e[i].x, y = e[i].y;
    		if(x == y){
    			vis[i] = 1;
    			continue;
    		}
    		if(Check(x, y)){
    			Link(x, idx), Link(idx, y);
    			++tot;
    		}
    		else{
    			Split(x, y);
    			int root = t[y].id;
    			vis[root - n] = 1;
    			Splay(root);
    			t[t[root].ch[0]].fa = t[t[root].ch[1]].fa = 0;
    			Link(x, idx), Link(idx, y);
    		}
    		while(l < i && vis[l]) ++l;
    		if(tot >= n) ans = Min(ans, e[i].w - e[l].w);
    	}
    	
    	printf("%d", ans);
    	
    	return 0;
    }
    

    没看的了,咕了

  • 相关阅读:
    矩阵乘法(二):利用矩阵快速幂运算完成递推
    更改codeblock编译后程序的图标
    如何在VS2008下使用FLTK
    Python type() 函数
    Python range() 函数用法
    Python len()方法
    Python filter() 函数
    Python bool() 函数
    数据类型
    JAVA标识符
  • 原文地址:https://www.cnblogs.com/bingoyes/p/11592628.html
Copyright © 2020-2023  润新知