【moban】treap板子
其实感觉treap和splay一样都是玄学?orz 不过这个选随机数种子挺好van的
LOJ104普通平衡树
题就不放了,基本上操作和splay一样,只是这个是tree + heap 就是随机一个值,让值小的(大的) 放在最高头(堆顶)来进行旋转,只会在删除和添加的地方旋转,利用随机树保证其平衡,而splay是每次操作都对整棵树进行选择,通过均摊来保证平衡(玄学平衡)
orz orz orz别的二叉查找树该怎么操作怎么操作。
#include<cstdio> #include<iostream> #include<algorithm> #include<cmath> #define zig(x) zigzag(x,1) #define zag(x) zigzag(x,2) using namespace std; const int maxn = 200005; int n,tot,rt; int alls; struct node { int ls,rs,dat,pri,fa,cc,siz; }Z[maxn]; void putup(int x) { Z[x].siz=Z[x].cc+Z[Z[x].ls].siz+Z[Z[x].rs].siz; } void putupall(int x) { putup(x); if(Z[x].fa) putupall(Z[x].fa); } int LJ[maxn],ljt; int getnew() { int p ; if(ljt) p = LJ[ljt--]; p = ++tot; Z[p].ls = Z[p].rs = Z[p].pri = Z[p].dat = Z[p].fa = Z[p].cc = Z[p].siz = 0; return p; } void zigzag(int x,int knd) { int y=Z[x].fa,z=Z[y].fa; if(z) { if(Z[z].ls==y) Z[z].ls = x; else Z[z].rs = x; } Z[x].fa = z; Z[y].fa = x; if(knd==1) { Z[y].ls = Z[x].rs; Z[Z[y].ls].fa = y; Z[x].rs = y; } else { Z[y].rs = Z[x].ls; Z[Z[y].rs].fa = y; Z[x].ls = y; } if(!Z[x].fa) rt = x; putup(y); putup(x); } void ins(int key) { ++alls; if(!rt) { rt = getnew(); Z[rt].dat = key; Z[rt].pri = rand(); Z[rt].ls = Z[rt].rs = Z[rt].fa = 0; Z[rt].siz = Z[rt].cc = 1; return; } int now = rt,p; while(now) { if(Z[now].dat==key) { Z[now].cc++; Z[now].siz++; putupall(now); return; } else if(Z[now].dat<key) { if(Z[now].rs)now = Z[now].rs; else { p = getnew(); Z[now].rs = p; break; } } else { if(Z[now].ls)now = Z[now].ls; else { p = getnew(); Z[now].ls = p; break; } } } Z[p].dat = key; Z[p].siz=Z[p].cc=1; Z[p].ls = Z[p].rs = 0 ; Z[p].fa = now; Z[p].pri = rand(); putupall(p); while(Z[p].pri<Z[Z[p].fa].pri) { if(Z[Z[p].fa].ls==p) zig(p); else zag(p); } } int fi(int key) { int p = rt; while(p) { if(Z[p].dat==key) return p; if(Z[p].dat<key) p = Z[p].rs; else p = Z[p].ls; } return 0; } int getmin(int p) { while(Z[p].ls) p = Z[p].ls; return p; } int getmax(int p) { while(Z[p].rs) p = Z[p].rs; return p; } void del(int key) { --alls; if(!alls) rt = 0; int p = fi(key); if(!p) return; if(Z[p].cc>1) { --Z[p].cc; --Z[p].siz; putupall(p); return; } while(Z[p].ls||Z[p].rs) { if(!Z[p].ls) { zag(Z[p].rs); continue; } if(!Z[p].rs) { zig(Z[p].ls); continue; } if(Z[Z[p].ls].pri<Z[Z[p].rs].pri) zig(Z[p].ls); else zag(Z[p].rs); } putup(p); if(Z[p].fa) { if(p==Z[Z[p].fa].ls) Z[Z[p].fa].ls = 0; else Z[Z[p].fa].rs = 0; putupall(Z[p].fa); } LJ[++ljt] = p; } int getk(int k) { int p = rt; while(k) { if(Z[Z[p].ls].siz>=k) p = Z[p].ls; else if(Z[Z[p].ls].siz+Z[p].cc<k) k-=Z[Z[p].ls].siz+Z[p].cc,p = Z[p].rs; else return p; } return 0; } int getpaiming(int key) { int p = fi(key); if(p==rt) return Z[Z[p].ls].siz+1; int now = rt; int kk = 0; while(now) { if(now==p) { kk+=Z[Z[now].ls].siz; break; }; if(Z[now].dat<key) { kk += Z[Z[now].ls].siz + Z[now].cc ; now = Z[now].rs; } else now = Z[now].ls; } return kk+1; } int getqianqu(int key) { int p = rt; int ans = -0x3f3f3f3f; while(p) { if(Z[p].dat>=key) p = Z[p].ls; else { if(Z[p].dat>ans) ans = Z[p].dat; p = Z[p].rs; } } return ans; } int gethouji(int key) { int p = rt; int ans = 0x3f3f3f3f; while(p) { if(Z[p].dat<=key) p = Z[p].rs; else { if(Z[p].dat<ans) ans = Z[p].dat; p = Z[p].ls; } } return ans; } int main() { // freopen("aha.out","w",stdout); srand(19360924); scanf("%d",&n); for(int i=1;i<=n;i++) { int opt,x; scanf("%d%d",&opt,&x); if(opt==1) ins(x); else if(opt==2) del(x); else if(opt==3) printf("%d\n",getpaiming(x)); else if(opt==4) printf("%d\n",Z[getk(x)].dat); else if(opt==5) printf("%d\n",getqianqu(x)); else printf("%d\n",gethouji(x)); } }