BZOJ 3224 Splay
2016-06-01 23:33
218 查看
【题目分析】
显然是一道平衡树的裸题。然而我用treap完成之后又尝试用splay。无论是旋转还是插入删除,都已经做的很好了,但是size数组没有维护好。心好累,不想再改了,就这样吧。直接上代码,希望有人能找到我的错误
显然是一道平衡树的裸题。然而我用treap完成之后又尝试用splay。无论是旋转还是插入删除,都已经做的很好了,但是size数组没有维护好。心好累,不想再改了,就这样吧。直接上代码,希望有人能找到我的错误
/************************************************************** Problem: 3224 User: sdfzwxl Language: C++ Result: Wrong_Answer ****************************************************************/ #include <cstdio> #include <iostream> #include <cstring> using namespace std; const int maxn=100010; int c[maxn][2],cnt,flag=0,v[maxn],f[maxn],w[maxn],size[maxn],n,t1,t2,rt,x,ans=0,b; inline int min(int a,int b) {return a>b?b:a;} inline void up(int p) {size[p]=size[c[p][0]]+size[c[p][1]]+w[p];} inline void rot(int x,int &k) { int y=f[x],z=f[y],l,r; if (c[y][0]==x) l=0; else l=1; r=l^1; if (y==k) k=x; else{if (c[z][0]==y) c[z][0]=x;else c[z][1]=x;} f[x]=z;f[y]=x;f[c[x][r]]=y; c[y][l]=c[x][r];c[x][r]=y; size[x]=size[y]; up(y); // size[y]=size[c[y][0]]+size[c[y][1]]+w[y]; } inline void splay(int x,int &k) { int y,z; while (x!=k) { y=f[x];z=f[y]; if (y!=k) { if ((c[y][0]==x)^(c[z][0]==y)) rot(x,k); else rot(y,k); } rot(x,k); } } inline void ins(int &k,int x,int fa) { if (!k){k=++cnt;v[k]=x;f[k]=fa;size[k]=1;w[k]=1;splay(k,rt);return;} size[k]++; if (x==v[k]) w[k]++; else if (x<v[k]) ins(c[k][0],x,k); else if (x>v[k]) ins(c[k][1],x,k); up(k); } inline void del(int &k,int x) { if (k==0) return ; if (v[k]==x) { if (w[k]>1) { w[k]--; size[k]--; return ; } else{ if (c[k][0]*c[k][1]==0) { f[c[k][0]+c[k][1]]=f[k]; k=c[k][0]+c[k][1]; } else if (size[c[k][0]]<size[c[k][1]]){ if (c[f[k]][1]==k) rot(c[k][1],rt),del(c[k][1],x); else rot(c[k][1],rt),del(c[k][0],x); } else if (c[f[k]][0]==k) rot(c[k][1],rt),del(c[k][0],x); else rot(c[k][1],rt),del(c[k][1],x); } up(k); return; } size[k]--; if (v[k]<x) del(c[k][1],x); else del(c[k][0],x); up(k); } inline int qr(int k,int x) { if (!k) return 0; if (x<v[k]) return qr(c[k][0],x); if (x==v[k]) return size[c[k][0]]+1; if (x>v[k]) return size[c[k][0]]+w[k]+qr(c[k][1],x); } inline int qn(int k,int x) { if (!k) return 0; if (x<=size[c[k][0]]) return qn(c[k][0],x); if (x>size[c[k][0]]+w[k]) return qn(c[k][1],x-size[c[k][0]]-w[k]); else return v[k]; } inline void qp(int k,int x) { if (!k) return; if (v[k]<x){t1=v[k];qp(c[k][1],x);} else qp(c[k][0],x); } inline void qs(int k,int x) { if (!k) return; if (v[k]>x){t2=v[k];qs(c[k][0],x);} else qs(c[k][1],x); } int main() { scanf("%d",&n); for (int i=1;i<=n;++i) { scanf("%d%d",&x,&b); switch(x) { case 1:ins(rt,b,0); break; case 2:del(rt,b); break; case 3:printf("%d\n",qr(rt,b)); break; case 4:printf("%d\n",qn(rt,b)); break; case 5:qp(rt,b); printf("%d\n",t1);break; case 6:qs(rt,b); printf("%d\n",t2);break; } } }
相关文章推荐
- NOI2005 维修数列
- [bzoj1500][NOI2005]维修数列
- [bzoj1208] [HNOI2004]宠物收养所
- [bzoj1269][AHOI2006]文本编辑器editort
- [bzoj1503][NOI2004]郁闷的出纳员
- [BZOJ1014][JSOI2008][Splay][RKHash]火星人prefix
- [BZOJ1500][NOI2005][Splay]维修数列
- [BZOJ3196][TYVJ3196][树套数][区间第k大]二逼平衡树
- 初识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!"(区间最大连续数组和)
- java 实现平衡树