本来我是在开开心心(泪流满面)地刷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;
}