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;
    }
    
  • 相关阅读:
    消息队列技术
    NET Core中使用Apworks
    TCP基础
    Oracle停止一个JOB
    如何在Java 8中愉快地处理日期和时间
    mysql字符串区分大小写的问题
    【已解决】javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint
    spring boot 1.4默认使用 hibernate validator
    mysql shell
    android:background="@drawable/home_tab_bg"
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/8885249.html
Copyright © 2011-2022 走看看