BZOJ 3224: Tyvj 1728 普通平衡树
3224: Tyvj 1728 普通平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 9286 Solved: 3935
[Submit][Status][Discuss]
Description
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
Input
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)
Output
对于操作3,4,5,6每行输出一个数,表示对应答案
Sample Input
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
Sample Output
106465
84185
492737
84185
492737
HINT
1.n的数据范围:n<=100000
2.每个数的数据范围:[-1e7,1e7]
数据如下http://pan.baidu.com/s/1jHMJwO2
Source
分析:
还是模板题...讲道理这道题我写了3遍才AC...QAQ...
代码:
1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 //by NeighThorn 6 #define inf 1e7+7 7 using namespace std; 8 9 const int maxn=100000+5; 10 11 int n,opt; 12 int root,tot,w[maxn],ls[maxn],rs[maxn],fa[maxn],cnt[maxn],siz[maxn]; 13 14 inline void zig(int x){ 15 int y=fa[x],tmp=siz[y]; 16 if(rs[x]) 17 ls[y]=rs[x],fa[rs[x]]=y,siz[y]=siz[y]-siz[x]+siz[rs[x]],siz[x]=tmp; 18 else 19 ls[y]=0,siz[y]=siz[y]-siz[x],siz[x]=tmp; 20 fa[x]=fa[y]; 21 if(fa[x]){ 22 if(ls[fa[x]]==y) 23 ls[fa[x]]=x; 24 else 25 rs[fa[x]]=x; 26 } 27 fa[y]=x,rs[x]=y; 28 } 29 30 inline void zag(int x){ 31 int y=fa[x],tmp=siz[y]; 32 if(ls[x]) 33 rs[y]=ls[x],fa[ls[x]]=y,siz[y]=siz[y]-siz[x]+siz[ls[x]],siz[x]=tmp; 34 else 35 rs[y]=0,siz[y]=siz[y]-siz[x],siz[x]=tmp; 36 fa[x]=fa[y]; 37 if(fa[x]){ 38 if(ls[fa[x]]==y) 39 ls[fa[x]]=x; 40 else 41 rs[fa[x]]=x; 42 } 43 fa[y]=x,ls[x]=y; 44 } 45 46 inline void splay(int x,int z){ 47 while(fa[x]!=z){ 48 int y=fa[x]; 49 if(fa[y]==z){ 50 if(ls[y]==x) 51 zig(x); 52 else 53 zag(x); 54 } 55 else{ 56 if(ls[fa[y]]==y){ 57 if(ls[y]==x) 58 zig(y),zig(x); 59 else 60 zag(x),zig(x); 61 } 62 else{ 63 if(rs[y]==x) 64 zag(y),zag(x); 65 else 66 zig(x),zag(x); 67 } 68 } 69 } 70 if(!z) 71 root=x; 72 } 73 74 inline void ins(int rt,int x){ 75 if(!rt) 76 w[++tot]=x,siz[tot]=1,cnt[tot]=1,root=tot; 77 else if(w[rt]==x) 78 cnt[rt]++,siz[rt]++,splay(rt,0); 79 else if(x<w[rt]){ 80 if(!ls[rt]) 81 w[++tot]=x,cnt[tot]=siz[tot]=1,siz[rt]++,fa[tot]=rt,ls[rt]=tot,splay(tot,0); 82 else 83 siz[rt]++,ins(ls[rt],x); 84 } 85 else{ 86 if(!rs[rt]) 87 w[++tot]=x,cnt[tot]=siz[tot]=1,siz[rt]++,fa[tot]=rt,rs[rt]=tot,splay(tot,0); 88 else 89 siz[rt]++,ins(rs[rt],x); 90 } 91 } 92 93 inline void del(int rt,int x){ 94 if(w[rt]==x){ 95 splay(rt,0); 96 if(cnt[rt]>1) 97 cnt[rt]--,siz[rt]--; 98 else{ 99 int l=ls[rt],r=rs[rt]; 100 if(!l) 101 ls[rt]=rs[rt]=fa[rt]=siz[rt]=cnt[rt]=0,fa[r]=0,root=r; 102 else{ 103 while(rs[l]) 104 l=rs[l]; 105 splay(l,rt);ls[rt]=rs[rt]=fa[rt]=siz[rt]=cnt[rt]=0;fa[r]=l,rs[l]=r,siz[l]+=siz[r];root=l,fa[l]=0; 106 } 107 } 108 } 109 else if(x<w[rt]) 110 del(ls[rt],x); 111 else 112 del(rs[rt],x); 113 } 114 115 inline int pre(int rt,int x){ 116 int res=-inf; 117 while(rt){ 118 if(w[rt]<x) 119 res=max(res,w[rt]),rt=rs[rt]; 120 else 121 rt=ls[rt]; 122 } 123 return res; 124 } 125 126 inline int suf(int rt,int x){ 127 int res=inf; 128 while(rt){ 129 if(w[rt]>x) 130 res=min(res,w[rt]),rt=ls[rt]; 131 else 132 rt=rs[rt]; 133 } 134 return res; 135 } 136 137 inline int rank(int rt,int x){ 138 if(w[rt]==x){ 139 splay(rt,0); 140 if(!ls[rt]) 141 return 1; 142 else 143 return siz[ls[rt]]+1; 144 } 145 else if(x<w[rt]) 146 return rank(ls[rt],x); 147 else 148 return rank(rs[rt],x); 149 } 150 151 inline int query(int rt,int x){ 152 if(!ls[rt]){ 153 if(cnt[rt]>=x){ 154 splay(rt,0); 155 return w[rt]; 156 } 157 else 158 return query(rs[rt],x-cnt[rt]); 159 } 160 else{ 161 if(siz[ls[rt]]>=x) 162 return query(ls[rt],x); 163 else if(siz[ls[rt]]+cnt[rt]>=x){ 164 splay(rt,0); 165 return w[rt]; 166 } 167 else 168 return query(rs[rt],x-siz[ls[rt]]-cnt[rt]); 169 } 170 } 171 172 signed main(void){ 173 memset(ls,0,sizeof(ls)); 174 memset(rs,0,sizeof(rs)); 175 memset(fa,0,sizeof(fa)); 176 memset(cnt,0,sizeof(cnt)); 177 memset(siz,0,sizeof(siz)); 178 scanf("%d",&n);root=tot=0; 179 for(int i=1,x;i<=n;i++){ 180 scanf("%d%d",&opt,&x); 181 if(opt==1) 182 ins(root,x); 183 else if(opt==2) 184 del(root,x); 185 else if(opt==3) 186 printf("%d\n",rank(root,x)); 187 else if(opt==4) 188 printf("%d\n",query(root,x)); 189 else if(opt==5) 190 printf("%d\n",pre(root,x)); 191 else 192 printf("%d\n",suf(root,x)); 193 } 194 return 0; 195 }
by NeighThorn