• 左偏树(Leftist-tree) Luogu P3377 模板


    左偏树(Leftist-tree)

    性质

    • 节点的键值小于或等于左右子节点的键值。这是左偏树的堆性质。
    • 节点的左子节点的距离不小于右子节点的距离。
    • 节点的距离等于它的右子节点距离加一。
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #define N 200001
    using namespace std;
    const int INF = 0x3f3f3f3f;
    struct node{
    	int val,lc,rc,dis,fa;
    }tree[N];
    int tot,n,m;
    int init(){
    	for(int i = 1;i <= n;++i){
    		tree[i].lc = tree[i].rc = tree[i].dis = 0;
    		tree[i].fa = i;
    	}
    }
    int merge(int x,int y){
    	if(x == 0) return y;
    	if(y == 0) return x;
    	if(tree[x].val > tree[y].val || (tree[x].val == tree[y].val && x > y) )
    		swap(x,y);
    	tree[x].rc = merge(tree[x].rc,y);
    	tree[tree[x].rc].fa = x;
    	if(tree[tree[x].rc].dis > tree[tree[x].lc].dis)
    		swap(tree[x].rc,tree[x].lc);
    	tree[x].dis = tree[x].rc == 0 ? 0 : tree[tree[x].rc].dis + 1;
    }
    int findset(int x){
    	while(tree[x].fa != x){
    		x = tree[x].fa;
    	}
    	return x;
    }
    int add(int val,int x){
    	tree[tot].lc = tree[tot].rc = tree[tot].dis = 0;
    	tree[tot++].val = val;
    	return merge(tot - 1,x);	
    }
    int del(int x){
    	int l = tree[x].lc,r = tree[x].rc;
    	tree[x].fa = tree[x].lc = tree[x].rc = tree[x].dis = 0;
    	tree[x].val = -INF;
    	tree[l].fa = l;
    	tree[r].fa = r;
    	return merge(l,r);
    }
    int build()
    {
    	queue<int> Q;
    	for(int i = 1;i <= n;++i)
    		Q.push(i);
    	while(!Q.empty()){
    		if(Q.size() == 1) break;
    		else{
    			int x = Q.front();Q.pop();
    			int y = Q.front();Q.pop();
    			Q.push(merge(x,y));
    		}
    	}
    	int final = Q.front();Q.pop();
    	return final;
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	init();
    	for(int i = 1;i <= n;++i){
    		scanf("%d",&tree[i].val);
    	}
    	int op,a,b;
    	for(int i = 1;i <= m;++i){
    		scanf("%d",&op);
    		if(op == 1){
    			scanf("%d%d",&a,&b);
    			int fx = findset(a),fy = findset(b);
    			if(tree[a].val == INF || tree[b].val == INF || fx == fy){
    				continue;
    			} else {
    				merge(fx,fy);
    			}
    		} else {
    			scanf("%d",&a);
    			if(tree[a].val == -INF){
    				printf("-1
    ");
    			} else {
    				int tmp = findset(a);
    				printf("%d
    ",tree[tmp].val);
    				del(tmp);
    			}
    		}
    	}
    	return 0;
    }
    
    岂能尽如人意,但求无愧我心
  • 相关阅读:
    linux下创建virtualenv时指定python版本
    Centos7系统如何不重启系统识别新添加的硬盘?
    centos7系统下hostname解析
    Linux之shell脚本for、while、case语句的高级用法
    Linux自制编译内核
    Centos7系统详细的启动流程
    cpio的用法
    Linux之删除带有空格的文件(而不是目录)
    Linux之特殊的环境变量IFS以及如何删除带有空格的目录
    zabbix使用自定义脚本监控内存
  • 原文地址:https://www.cnblogs.com/Zforw/p/10780056.html
Copyright © 2020-2023  润新知