首页 > 代码库 > Bzoj3224 / Tyvj 1728 普通替罪羊树
Bzoj3224 / Tyvj 1728 普通替罪羊树
Submit: 12015 Solved: 5136
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.每个数的数据范围:[-2e9,2e9]
Source
平衡树
替罪羊树
曾经我一直以为替罪羊树就是不平衡的时候拍扁了重建……
真是拿衣服
从yhx那里get了神奇的删点方法:找到它的前驱pre,用pre代替它←虽然只有一句话,但这是整道题最麻烦的地方
http://blog.csdn.net/sdfzyhx/article/details/70212142
1 /*by SilverN*/ 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<vector> 8 using namespace std; 9 const int mxn=120010; 10 int read(){ 11 int x=0,f=1;char ch=getchar(); 12 while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 13 while(ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 14 return x*f; 15 } 16 struct node{ 17 int l,r; 18 int val,sz; 19 int cnt; 20 bool operator < (const node b)const{ 21 return val<b.val; 22 } 23 }t[mxn],vt[mxn]; 24 int rot=0; 25 int sz=0,cnt=0; 26 int st[mxn],top=0; 27 int flag=0,faf; 28 int newnode(){ 29 int res=0; 30 if(top)res=st[top--]; 31 else res=++cnt; 32 t[res].sz=t[res].l=t[res].r=t[res].cnt=0; 33 return res; 34 } 35 void pushup(int x){ 36 t[x].sz=t[t[x].l].sz+t[t[x].r].sz+t[x].cnt;return; 37 } 38 void Build(int l,int r,int &rt){ 39 if(l>r){rt=0;return;} 40 int mid=(l+r)>>1; 41 rt=newnode(); 42 t[rt].val=vt[mid].val; 43 t[rt].cnt=vt[mid].cnt; 44 t[rt].sz=t[rt].cnt; 45 Build(l,mid-1,t[rt].l); 46 Build(mid+1,r,t[rt].r); 47 pushup(rt); 48 return; 49 } 50 void insert(int &rt,int x){ 51 if(!rt){ 52 rt=newnode(); 53 t[rt].val=x; 54 t[rt].cnt=t[rt].sz=1; 55 return; 56 } 57 t[rt].sz++; 58 if(t[rt].val==x){ 59 t[rt].cnt++; 60 return; 61 } 62 if(x<t[rt].val)insert(t[rt].l,x); 63 else insert(t[rt].r,x); 64 if(t[t[rt].l].sz/(double)t[rt].sz>0.666)flag=rt; 65 if(flag==t[rt].l || flag==t[rt].r)faf=rt; 66 pushup(rt); 67 return; 68 } 69 void del(int rt){ 70 if(!rt)return; 71 vt[++sz]=t[rt]; 72 st[++top]=rt; 73 del(t[rt].l); 74 del(t[rt].r); 75 return; 76 } 77 int pre(int rt,int x){ 78 int res=-2e9-1,pos=0; 79 while(rt){ 80 if(t[rt].val>=x){ 81 rt=t[rt].l; 82 } 83 else{ 84 if(t[rt].val>res){res=t[rt].val;pos=rt;} 85 rt=t[rt].r; 86 } 87 } 88 return pos; 89 } 90 int sub(int rt,int x){ 91 int res=2e9+1,pos=0; 92 while(rt){ 93 if(t[rt].val<=x){ 94 rt=t[rt].r; 95 } 96 else{ 97 if(t[rt].val<res){res=t[rt].val;pos=rt;} 98 rt=t[rt].l; 99 }100 }101 return pos;102 }103 int st2[mxn],top2=0,fafa;104 void Q_erase(int &rt,int x){105 // if(!rt && x==299181)while(1);106 if(t[rt].val==x){107 t[rt].cnt--;108 t[rt].sz--;109 if(!t[rt].cnt){110 if(t[rt].l*t[rt].r==0){rt=t[rt].l+t[rt].r;return;}111 int p=t[rt].l;112 while(t[p].r){st2[++top2]=p;p=t[p].r;}113 if(top2){114 t[st2[top2]].r=t[p].l;115 pushup(st2[top2]);116 t[p].l=t[rt].l;117 t[p].r=t[rt].r;118 while(top2)pushup(st2[top2--]);119 }120 else t[p].r=t[rt].r;121 if(fafa){122 if(t[fafa].l==rt) t[fafa].l=p;123 else t[fafa].r=p;124 }125 pushup(p);126 pushup(t[rt].l);127 rt=p;128 }129 pushup(fafa);130 return;131 }132 fafa=rt;133 if(x<t[rt].val)Q_erase(t[rt].l,x);134 else Q_erase(t[rt].r,x);135 pushup(rt);136 return;137 }138 int Q_rank(int rt,int x){139 int res=0;140 while(rt){141 if(t[rt].val<x){142 res+=t[t[rt].l].sz+t[rt].cnt;143 rt=t[rt].r;144 }145 else rt=t[rt].l;146 }147 return res+1;148 }149 int Q_num(int rt,int k){150 int res=0;151 while(rt){152 if(t[t[rt].l].sz>=k){153 res=t[rt].val;154 rt=t[rt].l;155 }156 else if(t[t[rt].l].sz+t[rt].cnt>=k)return t[rt].val;157 else k-=t[t[rt].l].sz+t[rt].cnt,rt=t[rt].r;158 }159 return res;160 }161 void Debug(int x){162 if(!x)return;163 printf("#%d: v:%d l:%d r:%d sz:%d cnt:%d\n",164 x,t[x].val,t[x].l,t[x].r,t[x].sz,t[x].cnt);165 Debug(t[x].l);Debug(t[x].r);166 }167 int n;168 int main(){169 // freopen("in.txt","r",stdin);170 // freopen("out.out","w",stdout);171 int i,j;172 n=read();173 int op,x;174 int tct=0;175 while(n--){176 op=read();x=read();177 if(op!=1)tct++;178 switch(op){179 case 1:{180 flag=faf=0;sz=0;181 insert(rot,x);182 if(flag){183 del(flag);184 sort(vt+1,vt+sz+1);185 if(flag==rot)Build(1,sz,rot);186 else Build(1,sz,(t[faf].l==flag)?t[faf].l:t[faf].r);187 }188 break;189 }190 case 2:{fafa=0;Q_erase(rot,x);break;}191 case 3:{192 int ans=Q_rank(rot,x);193 printf("%d\n",ans);194 break;195 }196 case 4:{197 int ans=Q_num(rot,x);198 printf("%d\n",ans);199 break;200 }201 case 5:{202 int res=pre(rot,x);203 printf("%d\n",t[res].val);204 break;205 }206 case 6:{207 int res=sub(rot,x);208 printf("%d\n",t[res].val);209 break;210 }211 case 7:{212 Debug(rot);213 break;214 }215 }216 }217 return 0;218 }
Bzoj3224 / Tyvj 1728 普通替罪羊树
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。