zoukankan      html  css  js  c++  java
  • [洛谷P3377]【模板】左偏树(可并堆)

    题目大意:
    给你n个小根堆,每个堆初始有一个元素。有两个操作:
    1. 把第x个数和第y个数所在的堆合并(如果第x个数或第y个数已经被删除or它们已经在同一个堆内则忽略)
    2. 输出第x个数所在堆的堆顶元素,并将这个堆顶元素弹出堆(如果第x个数不存在则输出-1)
    如果第$a_i$个数与第$a_j$个数相同,则比较i与j的大小。
    解题思路:
    可并堆嘛。话说随机化期望值还是蛮高的,于是随机堆+并查集水过。
    嗯……平板电视大法也不错呀,不过空间占用貌似有点多啊(还好还好没超)。

    随机堆:

    C++ Code:

    #include<bits/stdc++.h>
    int n,m,fa[100005],vis[100005];
    inline int readint(){
    	int c=getchar(),d=0;
    	for(;!isdigit(c);c=getchar());
    	for(;isdigit(c);c=getchar())
    	d=(d<<3)+(d<<1)+(c^'0');
    	return d;
    }
    struct Heap{
    	Heap *ls,*rs;
    	int s,id;
    	Heap(int t=0,int num=0){
    		ls=rs=NULL;
    		s=t;
    		id=num;
    	}
    	inline bool operator<(const Heap& rhs)const{
    		if(s!=rhs.s)return s<rhs.s;
    		return id<rhs.id;
    	}
    }*a[100005];
    int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
    Heap* merge(Heap*& a,Heap*& b){
    	if(a==NULL)return b;
    	if(b==NULL)return a;
    	if((*b)<(*a))std::swap(a,b);
    	if(rand()&1)a->rs=merge(a->rs,b);else
    	a->ls=merge(a->ls,b);
    	return a;
    }
    int Delete(Heap*& p){
    	int id=p->id;
    	p=merge(p->ls,p->rs);
    	return id;
    }
    int main(){
    	#ifdef LOCALJUDGE
    	freopen("testdata.in","r",stdin);
    	freopen("testdata.out","w",stdout);
    	#endif
    	srand(20170607);
    	memset(vis,0,sizeof vis);
    	n=readint(),m=readint();
    	for(int i=1;i<=n;++i)fa[i]=i,a[i]=new Heap(readint(),i);
    	while(m--){
    		int opt=readint();
    		if(opt==1){
    			int x=readint(),y=readint();
    			int a=find(x),b=find(y);
    			if(vis[y]||vis[x]||!a||!b)continue;
    			if(a!=b){
    				fa[b]=a;
    				::a[a]=merge(::a[a],::a[b]);
    			}
    		}else{
    			int x=readint();
    			int p=find(x);
    			if(!p||vis[x]||a[p]==NULL){
    				puts("-1");
    				continue;
    			}
    			printf("%d
    ",a[p]->s);
    			int id=Delete(a[p]);
    			vis[id]=1;
    		}
    	}
    	return 0;
    }
    

    pbds:

    C++ Code:

    #include<bits/stdc++.h>
    #include<ext/pb_ds/priority_queue.hpp>
    using namespace std;
    __gnu_pbds::priority_queue<pair<int,int>,greater<pair<int,int> >,__gnu_pbds::thin_heap_tag>a[100005];
    inline int readint(){
    	int c=getchar(),d=0;
    	for(;!isdigit(c);c=getchar());
    	for(;isdigit(c);c=getchar())d=(d<<3)+(d<<1)+(c^'0');
    	return d;
    }
    bool vis[100005];
    int n=readint(),m=readint(),fa[100005];
    inline int dad(int x){return x==fa[x]?x:fa[x]=dad(fa[x]);}
    int main(){
    	memset(vis,0,sizeof vis);
    	for(int i=1;i<=n;++i)a[i].push(make_pair(readint(),i)),fa[i]=i;
    	while(m--){
    		int opt=readint();
    		if(opt==1){
    			int x=readint(),y=readint();
    			if(vis[x]||vis[y])continue;
    			x=dad(x),y=dad(y);
    			if(x!=y){
    				fa[y]=x;
    				a[x].join(a[y]);
    			}
    		}else{
    			int x=readint();
    			int f=dad(x);
    			if(vis[x]){
    				puts("-1");
    				continue;
    			}
    			pair<int,int>p=a[f].top();
    			a[f].pop();
    			printf("%d
    ",p.first);
    			vis[p.second]=1;
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Yield Usage Understanding
    Deadclock on calling async methond
    How to generate file name according to datetime in bat command
    Run Unit API Testing Which Was Distributed To Multiple Test Agents
    druid的关键参数+数据库连接池运行原理
    修改idea打开新窗口的默认配置
    spring boot -thymeleaf-url
    @pathvariable和@RequestParam的区别
    spring boot -thymeleaf-域对象操作
    spring boot -thymeleaf-遍历list和map
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/8885249.html
Copyright © 2011-2022 走看看