bzoj 3224 普通平衡树
2016-07-17 17:41
267 查看
算是平衡树最好的入门模板题了,几乎涵盖了平衡树所有的基础操作.
当然也可以用vector强行乱搞(毕竟暴力出奇迹).
splay
treap和vector不怎么会,如果想知道的话,详见hzwer的博客.
当然也可以用vector强行乱搞(毕竟暴力出奇迹).
splay
#include<cstdio> #define N 200005 using namespace std; int son [3],num [3],f ,a ; int opt,n,i,root,x,node,ans,flag; inline void Rotate(int x,int w)//1:左旋;2:右旋 w==1 { int y=f[x],z=f[y]; son[y][3-w]=son[x][w]; if (son[x][w]) f[son[x][w]]=y; f[x]=z; num[y][3-w]=num[x][w]; num[x][w]+=num[y][w]+1; if (z) { if (y==son[z][1]) son[z][1]=x; else son[z][2]=x; } f[y]=x;son[x][w]=y; } inline void splay(int x) { int y; while (f[x]) { y=f[x]; if (!f[y]) { if (x==son[y][1]) Rotate(x,2);else Rotate(x,1); continue; } if (y==son[f[y]][1]) { if (x==son[y][1]) Rotate(y,2),Rotate(x,2); else Rotate(x,1),Rotate(x,2); } else { if (x==son[y][2]) Rotate(y,1),Rotate(x,1); else Rotate(x,2),Rotate(x,1); } } root=x; } inline void inser(int x,int add) { if (add<=a[x]) { if (!son[x][1]) son[x][1]=++node,a[node]=add,f[node]=x; else inser(son[x][1],add); num[x][1]++; } else { if (!son[x][2]) son[x][2]=++node,a[node]=add,f[node]=x; else inser(son[x][2],add); num[x][2]++; } } inline void del(int x,int add) { if (!x) return; if (add==a[x]) { splay(x); if (!son[x][1]&&!son[x][2]){root=0;return;} if (!son[x][1]) {root=son[x][2];f[son[x][2]]=0;return;} if (!son[x][2]) {root=son[x][1];f[son[x][1]]=0;return;} int find=son[x][1],temp=son[x][2]; while (son[find][2]) find=son[find][2]; splay(find);son[find][2]=temp;f[temp]=find; return; } if (add<a[x]) del(son[x][1],add);else del(son[x][2],add); } inline int T_T(int x,int add,int now) { inser(root,add);splay(node); int ans=num[node][1]+1; del(node,add); return ans; } inline int O_O(int x,int k) { if (k==num[x][1]+1) return a[x]; if (k<=num[x][1]) return O_O(son[x][1],k); return O_O(son[x][2],k-num[x][1]-1); } inline int qian(int x,int k) { int find=son[x][1];if (!find) return 0; while (son[find][2]) find=son[find][2]; if (a[find]!=k) flag=1;return find; } inline int hou(int x,int k) { int find=son[x][2];if (!find) return 0; while (son[find][1]) find=son[find][1]; if (a[find]!=k) flag=1;return find; } int main() { freopen("A.in","r",stdin); freopen("A.out","w",stdout); scanf("%d",&n);root=0; for (i=1;i<=n;i++) { scanf("%d%d",&opt,&x); if (opt==1) inser(root,x),splay(node); if (opt==2) del(root,x); if (opt==3) printf("%d\n",T_T(root,x,0)); if (opt==4) printf("%d\n",O_O(root,x)); if (opt==5) { inser(root,x);splay(node); for (flag=0,ans=qian(root,x);!flag||!ans;splay(ans),ans=qian(root,x)); del(root,x);printf("%d\n",a[ans]); } if (opt==6) { inser(root,x);splay(node); for (flag=0,ans=hou(root,x);!flag||!ans;splay(ans),ans=hou(root,x)); del(root,x);printf("%d\n",a[ans]); } } return 0; }
treap和vector不怎么会,如果想知道的话,详见hzwer的博客.
相关文章推荐
- NOI2005 维修数列
- [bzoj1500][NOI2005]维修数列
- [bzoj1208] [HNOI2004]宠物收养所
- [bzoj1269][AHOI2006]文本编辑器editort
- [bzoj1503][NOI2004]郁闷的出纳员
- [BZOJ1014][JSOI2008][Splay][RKHash]火星人prefix
- [BZOJ1500][NOI2005][Splay]维修数列
- 初识splay tree ( hihocoder #1034 : 毁灭者问题 题解)
- 初识splay tree (三)
- 初识splay tree (二)
- 区间
- [HNOI 2004]宠物收养所
- [HNOI 2004]宠物收养所
- [NOI 2004]郁闷的出纳员
- [POJ 3580]Super Memo
- Splay树-Codevs 1296 营业额统计
- BZOJ 3223 文艺平衡树 【Splay】
- UVa 1400 "Ray, Pass me the dishes!"(区间最大连续数组和)
- 1500: [NOI2005]维修数列(Splay)
- HDU 1166 敌兵布阵(区间求和+单点更新)