【模板】左偏树(可并堆)
洛谷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 }