• LCT模板坑点总结


    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int MAXN=100005;
    int n,m;
    struct LCT {
    	int fa[MAXN],val[MAXN],rev[MAXN],ch[MAXN][2],sum[MAXN],tot;
    	int stk[MAXN],tp;
    	void up(int x) {
    		sum[x]=sum[ch[x][0]]^sum[ch[x][1]]^val[x];
    	}
    	void push_rev(int x) {
    		rev[x]^=1;
    		swap(ch[x][0],ch[x][1]);
    	}
    	void down(int x) {
    		if(rev[x]) {
    			rev[x]=0; 
    			push_rev(ch[x][0]);
    			push_rev(ch[x][1]);
    		}
    	}
    	int get(int x) {
    		return ch[fa[x]][1]==x;
    	}
    	bool isroot(int x) {
    		return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
    	}
    	void rotate(int x) {
    		int f1=fa[x],f2=fa[f1],id=get(x);
    		ch[f1][id]=ch[x][id^1]; fa[ch[f1][id]]=f1;
    		if(!isroot(f1)) ch[f2][get(f1)]=x; fa[x]=f2; //!!!!!
    		ch[x][id^1]=f1; fa[f1]=x;
    		up(f1);
    	}
    	void splay(int x) {
    		tp=0;
    		int y=x;
    		stk[++tp]=y; //!!!!!
    		while(!isroot(y)) stk[++tp]=y=fa[y];
    		while(tp) down(stk[tp--]);
    		while(!isroot(x)) { //!!!!!
    			int f1=fa[x],f2=fa[f1];
    			if(!isroot(f1)) {
    				if(get(x)==get(f1)) rotate(f1);
    				else rotate(x);
    			}
    			rotate(x);
    		}
    		up(x);
    	}
    	void access(int x) {
    		for(int y=0;x;y=x,x=fa[x])
    			splay(x),ch[x][1]=y,up(x);
    	}
    	void makeroot(int x) {
    		access(x);
    		splay(x);
    		push_rev(x);
    	}
    	int findroot(int x) {
    		access(x); splay(x);
    		while(ch[x][0]) x=ch[x][0];
    		splay(x);
    		return x;
    	}
    	void split(int x,int y) {
    		makeroot(x);
    		access(y);
    		splay(y);
    	}
    	void link(int x,int y) {
    		makeroot(x);
    		if(findroot(y)!=x) fa[x]=y;
    	}
    	void cut(int x,int y) {
    		makeroot(x);
    		if(findroot(y)==x&&fa[y]==x&&!ch[y][0]) { //!!!!!
    			fa[y]=ch[x][1]=0;
    			up(x);
    		}
    	}
    }tr;
    int main() {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++) scanf("%d",&tr.val[i]);
    	for(int i=1;i<=m;i++) {
    		int opt,x,y;
    		scanf("%d%d%d",&opt,&x,&y);
    		switch(opt) {
    			case 0: tr.split(x,y); printf("%d
    ",tr.sum[y]); break;
    			case 1:	tr.link(x,y); break;
    			case 2:	tr.cut(x,y); break;
    			case 3:	tr.makeroot(x); tr.val[x]=y; tr.up(x); break;
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    log4j的终极封装
    工具:docs网页笔记,gitbook,离线网网页
    java数据类型转换的常见方法
    java小结
    java判定数据(对象)类型
    婚纱摄影小结
    挖矿病毒是真么植入的
    centos根目录扩容,home目录减小容量
    java小结
    javap的使用
  • 原文地址:https://www.cnblogs.com/Gkeng/p/12003058.html
Copyright © 2020-2023  润新知