zoukankan      html  css  js  c++  java
  • 【模板】动态树(Link Cut Tree)

    模板

    \(\text{Code}\)

    #include <cstdio> 
    #include <iostream>
    #define IN inline
    #define RE register 
    using namespace std;
    
    const int N = 1e5 + 5;
    int n, m;
    
    struct LCT{
    	int st[N], c[N][2], fa[N], v[N], s[N], tg[N];
    	IN void pushup(int x){s[x] = s[c[x][0]] ^ s[c[x][1]] ^ v[x];}
    	IN void reverse(int x){tg[x] ^= 1, swap(c[x][0], c[x][1]);}
    	IN void pushdown(int x)
    	{
    		if (!tg[x]) return; tg[x] = 0;
    		if (c[x][0]) reverse(c[x][0]);
    		if (c[x][1]) reverse(c[x][1]);
    	}
    	IN int isroot(int x){return c[fa[x]][0] != x && c[fa[x]][1] != x;}
    	IN void rotate(int x)
    	{
    		int y = fa[x], z = fa[y], k = (c[y][1] == x), w = c[x][!k];
    		if (!isroot(y)) c[z][c[z][1] == y] = x; c[x][!k] = y, c[y][k] = w;
    		if (w) fa[w] = y; fa[y] = x, fa[x] = z, pushup(y);
    	}
    	IN void splay(int x)
    	{
    		int y = x, z = 0; st[++z] = y;
    		while (!isroot(y)) st[++z] = y = fa[y];
    		while (z) pushdown(st[z--]);
    		while (!isroot(x)){y=fa[x],z=fa[y]; if (!isroot(y)) rotate((c[y][0]==x)^(c[z][0]==y)?x:y); rotate(x);}
    		pushup(x);
    	}
    	IN void access(int x){for(RE int y=0; x; y=x, x=fa[x]) splay(x), c[x][1] = y, pushup(x);}
    	IN void makeroot(int x){access(x), splay(x), reverse(x);}
    	IN int findroot(int x){access(x), splay(x); while (c[x][0]) pushdown(x),x=c[x][0]; splay(x); return x;}
    	IN void split(int x, int y){makeroot(x), access(y), splay(y);}
    	IN void link(int x, int y){makeroot(x); if (findroot(y)^x) fa[x] = y;}
    	IN void cut(int x, int y){makeroot(x); if (findroot(y)==x&&fa[y]==x&&!c[y][0]) fa[y]=c[x][1]=0,pushup(x);}
    }T;
    
    int main()
    {
    	scanf("%d%d", &n, &m);
    	for(RE int i = 1; i <= n; i++) scanf("%d", &T.v[i]);
    	for(int op, x, y; m; --m)
    	{
    		scanf("%d%d%d", &op, &x, &y);
    		if (op == 0) T.split(x, y), printf("%d\n", T.s[y]);
    		else if (op == 1) T.link(x, y);
    		else if (op == 2) T.cut(x, y);
    		else T.splay(x), T.v[x] = y, T.pushup(x);
    	}
    }
    
  • 相关阅读:
    当今世界最为经典的十大算法投票进行时
    HDU_1203 I NEED A OFFER!
    POJ_2352 Stars(树状数组)
    HDU_1231 最大连续子序列
    POJ_3264 Balanced Lineup(线段树练手题)
    【转】休息几分种,学几个bash快捷键
    HDU_1013 Digital Roots
    HDU_1381 Crazy Search
    POJ_2528 Mayor's posters(线段树+离散化)
    zoj_1610 Count tht Color
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/15632820.html
Copyright © 2011-2022 走看看