输入格式
第一行为n,表示操作的个数,下面 n 行每行有两个数opt 和 x,opt表示操作的序号(1≤opt≤6)。
输出格式
对于操作 3、4、5、6 每行输出一个数,表示对应答案。
样例
输入数据 1
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
输出数据 1
106465
84185
492737
提示
- 传统题 1000ms 256MiB
-
说明
这是一道模板题。 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
- 插入 x 数;
- 删除 x 数(若有多个相同的数,应只删除一个);
- 查询 x 数的排名(若有多个相同的数,因输出最小的排名);
- 查询排名为 x 的数;
- 求 x 的前驱(前驱定义为小于 x,且最大的数);
- 求 x 的后继(后继定义为大于 x,且最小的数)。
- 数据范围:1≤n≤
,−≤x≤107
-
#include<bits/stdc++.h> using namespace std; struct S{ int lc,rc,vis,pos,cnt,sze; }t[500005];int n,m,cnt=0,rt=0; void zig(int &k){ int y=t[k].lc; t[k].lc=t[y].rc; t[y].rc=k; t[y].sze=t[k].sze; t[k].sze=t[t[k].lc].sze+t[t[k].rc].sze+t[k].cnt; k=y; } void zag(int &k){ int y=t[k].rc; t[k].rc=t[y].lc; t[y].lc=k; t[y].sze=t[k].sze; t[k].sze=t[t[k].lc].sze+t[t[k].rc].sze+t[k].cnt; k=y; } void inse(int &k,int key){ if(!k){ k=++cnt;t[k].vis=key;t[k].pos=rand(); t[k].cnt=t[k].sze=1;t[k].lc=t[k].rc=0; return ; } else ++t[k].sze; if(t[k].vis==key)++t[k].cnt; else if(key<t[k].vis){ inse(t[k].lc,key); if(t[t[k].lc].pos<t[k].pos)zig(k); } else { inse(t[k].rc,key); if(t[t[k].rc].pos<t[k].pos)zag(k); } return ; } void del(int &k,int key){ if(t[k].vis==key){ if(t[k].cnt>1)--t[k].cnt,--t[k].sze; else if(!t[k].lc || !t[k].rc)k=t[k].lc+t[k].rc; else if(t[t[k].lc].pos<t[t[k].rc].pos)zig(k),del(k,key); else zag(k),del(k,key); return ; } --t[k].sze; if(key<t[k].vis)del(t[k].lc,key); else del(t[k].rc,key); } int quepre(int key){ int k=rt,res=-0x3f3f3f3f; while(k){ if(t[k].vis<key)res=t[k].vis,k=t[k].rc; else k=t[k].lc; } return res; } int quenex(int key){ int k=rt,nex=0x3f3f3f3f; while(k){ if(t[k].vis>key)nex=t[k].vis,k=t[k].lc; else k=t[k].rc; } return nex; } int quekth(int k){ int x=rt; while(x){ if(t[t[x].lc].sze<k && t[t[x].lc].sze+t[x].cnt>=k)return t[x].vis; if(t[t[x].lc].sze>=k)x=t[x].lc; else k-=t[t[x].lc].sze+t[x].cnt,x=t[x].rc; } return 0; } int querank(int key){ int x=rt,res=0; while(x){ if(key==t[x].vis)return res+t[t[x].lc].sze+1; if(key<t[x].vis)x=t[x].lc; else res+=t[t[x].lc].sze+t[x].cnt,x=t[x].rc; } return res; } int main(){ int n; int op,x; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d%d",&op,&x); if(op==1)inse(rt,x); if(op==2)del(rt,x); if(op==3)cout<<querank(x)<<endl; if(op==4)cout<<quekth(x)<<endl; if(op==5)cout<<quepre(x)<<endl; if(op==6)cout<<quenex(x)<<endl; } return 0; }