【模板】左偏树(可并堆)

洛谷3377

可以轻松改成斜堆等可并堆

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define ls(x) (a[x].ls)
 4 #define rs(x) (a[x].rs) 
 5 using namespace std;
 6 int n,m,tot,x,y;
 7 struct heap{int ls,rs,val,fa,dis;}a[20000010];
 8 inline int read(){
 9     int k=0,f=1; char c=getchar();
10     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
11     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
12     return k*f;
13 }
14 inline int find(int x){while(x!=-1&&a[x].fa!=0) x=a[x].fa; return x;}
15 int merge(int x,int y){
16     if(!(x*y)) return x+y;
17     if(a[x].val>a[y].val||(a[x].val==a[y].val&&x>y)) swap(x,y);
18     a[rs(x)=merge(rs(x),y)].fa=x;
19     a[x].dis=a[rs(x)].dis+1;
20     if(a[rs(x)].dis>a[ls(x)].dis) swap(rs(x),ls(x));
21     return x;
22 }
23 int main(){
24     n=read(); m=read(); 
25     for(int i=1;i<=n;i++) a[i].val=read();
26     while(m--){ 
27         if(read()==1){ 
28             x=find(read()); y=find(read());
29             if(x!=-1&&y!=-1&&x!=y) int tmp=merge(x,y);
30         }
31         else
32             if((x=find(read()))==-1) puts("-1");
33             else printf("%d\n",a[x].val),a[x].fa=-1,a[merge(ls(x),rs(x))].fa=0;
34     }
35     return 0;
36 }
View Code

 

posted @ 2017-12-13 19:45  Driver_Lao  阅读(148)  评论(0编辑  收藏  举报