本来我是在开开心心(泪流满面)地刷Scapegoat Tree的,结果突然间就看见了一个奇奇怪怪的东西——斜堆。
因为昨天刚好学了左偏树,于是就来回忆了一发,然后发现。。。。。。。。。
既然有斜堆了为毛还要左偏树啊!!!
嗯好吧均摊确实不靠谱(此处@Splay),但你告诉我为毛斜堆跑得比左偏树快啊!!!
好吧常数我吃了。
其实斜堆和左偏树就一点不同,左偏树只有在维护左偏性质的时候才会交换左右子树,斜堆每次merge的时候都交换(各种均摊)
左偏树(我写程序自带常数TAT):
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=100000+10; int read(){ int x=0;char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x; } struct heapnode{ int l,r,f,v,d; }heap[N]; int merge(int x,int y){ if(!x||!y)return x+y; if(heap[x].v<heap[y].v)swap(x,y); heap[x].r=merge(heap[x].r,y); heap[heap[x].r].f=x; if(heap[heap[x].l].d<heap[heap[x].r].d)swap(heap[x].l,heap[x].r); if(!heap[x].r)heap[x].d=0; else heap[x].d=heap[heap[x].r].d+1; return x; } int find(int x){ return heap[x].f==x?x:heap[x].f=find(heap[x].f); } int pop(int x){ int l=heap[x].l,r=heap[x].r; heap[l].f=l;heap[r].f=r; heap[x].l=heap[x].r=heap[x].d=0; return merge(l,r); } int push(int x,int y){ return merge(x,y); } int main(){ int n; while(~scanf("%d",&n)){ for(int i=1;i<=n;i++){ heap[i].l=heap[i].r=heap[i].d=0; heap[i].f=i;heap[i].v=read(); } int q;q=read(); while(q--){ int x,y; x=read();y=read();x=find(x);y=find(y); if(x==y)puts("-1"); else{ heap[x].v/=2; int xx=pop(x); xx=push(xx,x); heap[y].v/=2; int yy=pop(y); yy=push(yy,y); int rt=merge(xx,yy); printf("%d\n",heap[rt].v); } } } return 0; }
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=100000+5; struct Node{ int l,r,v,f; }heap[N]; int merge(int x,int y){ if(!x||!y)return x+y; if(heap[x].v<heap[y].v)swap(x,y); heap[x].r=merge(heap[x].r,y); heap[heap[x].r].f=x; swap(heap[x].l,heap[x].r); return x; } int findroot(int x){ while(heap[x].f!=x)x=heap[x].f; return x; } int push(int x,int y){ return merge(x,y); } int pop(int x){ int l=heap[x].l,r=heap[x].r; heap[l].f=l;heap[r].f=r; heap[x].l=heap[x].r=0; return merge(l,r); } int main(){ int n; while(~scanf("%d",&n)){ for(int i=1;i<=n;i++){ heap[i].l=heap[i].r=0; heap[i].f=i; scanf("%d",&heap[i].v); } int m;scanf("%d",&m);int x,y; while(m--){ scanf("%d%d",&x,&y); x=findroot(x);y=findroot(y); if(x==y)puts("-1"); else{ int xx=pop(x);heap[x].v/=2; xx=push(xx,x); int yy=pop(y);heap[y].v/=2; yy=push(yy,y); int tmp=merge(xx,yy); printf("%d\n",heap[tmp].v); } } } return 0; }