您須要寫一種數據結構(可參考題目標題),來維護一些數,其中須要提供如下操做:
1. 插入x數
2. 刪除x數(如有多個相同的數,因只刪除一個)
3. 查詢x數的排名(如有多個相同的數,因輸出最小的排名)
4. 查詢排名爲x的數
5. 求x的前驅(前驅定義爲小於x,且最大的數)
6. 求x的後繼(後繼定義爲大於x,且最小的數)php
您須要寫一種數據結構(可參考題目標題),來維護一些數,其中須要提供如下操做:
1. 插入x數
2. 刪除x數(如有多個相同的數,因只刪除一個)
3. 查詢x數的排名(如有多個相同的數,因輸出最小的排名)
4. 查詢排名爲x的數
5. 求x的前驅(前驅定義爲小於x,且最大的數)
6. 求x的後繼(後繼定義爲大於x,且最小的數)php
第一行爲n,表示操做的個數,下面n行每行有兩個數opt和x,opt表示操做的序號(1<=opt<=6)ios
對於操做3,4,5,6每行輸出一個數,表示對應答案數據結構
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int MAXN=1000009; int fa[MAXN],ch[MAXN][2],key[MAXN],cnt[MAXN],size[MAXN],root,sz; void init() { root=sz=0; memset(ch,0,sizeof(ch)); memset(fa,0,sizeof(fa)); memset(cnt,0,sizeof(cnt)); memset(size,0,sizeof(size)); } inline void clear(int x) { fa[x]=ch[x][0]=ch[x][1]=cnt[x]=size[x]=0; } inline int get(int x) { return ch[fa[x]][1]==x; } inline void update(int x) { if(x){ size[x]=cnt[x]; if(ch[x][0]) size[x]+=size[ch[x][0]]; if(ch[x][1]) size[x]+=size[ch[x][1]]; } } inline void rotate(int x) { int father=fa[x],ffather=fa[father],which=get(x); ch[father][which]=ch[x][!which];fa[ch[father][which]]=father; ch[x][!which]=father;fa[father]=x; fa[x]=ffather; if(ffather) ch[ffather][ch[ffather][1]==father]=x; update(father); update(x); } inline void splay(int x) { for(int father;(father=fa[x]);rotate(x)) if(fa[father]) rotate((get(x)==get(father)?father:x)); root=x; } inline void insert(int x) { if(root==0) { root=++sz;fa[sz]=ch[sz][0]=ch[sz][1]=0;cnt[sz]=size[sz]=1;key[sz]=x;return; } int now=root,father=0; while(1){ if(key[now]==x) { cnt[now]++;update(now);update(father);splay(now);return; } father=now; now=ch[father][key[now]<x]; if(now==0){ sz++; fa[sz]=father; ch[father][key[father]<x]=sz; ch[sz][0]=ch[sz][1]=0; cnt[sz]=size[sz]=1; key[sz]=x; update(father); splay(sz); return; } } } inline int find(int x)//找到x的位置 { int now=root,ans=0; while(1){ if(x<key[now]) now=ch[now][0]; else{ if(ch[now][0]) ans+=size[ch[now][0]]; if(x==key[now]) { splay(now);return ans+1; } ans+=cnt[now]; now=ch[now][1]; } } } inline int rank(int x)//找到排名爲x的數 { int now=root; while(1){ if(ch[now][0]&&x<=size[ch[now][0]]) now=ch[now][0]; else{ int tmp=(ch[now][0]?size[ch[now][0]]:0)+cnt[now]; if(x<=tmp) return key[now]; x=x-tmp; now=ch[now][1]; } } } inline int pre()//找前驅 { int now=ch[root][0]; while(ch[now][1]) now=ch[now][1]; return now; } inline int suf()//找後繼 { int now=ch[root][1]; while(ch[now][0]) now=ch[now][0]; return now; } inline void del(int x)//刪去一個x { find(x); if(cnt[root]>1) { cnt[root]--;update(root);return; } else if(!ch[root][0]&&!ch[root][1]) { root=sz=0;clear(root);return; } else if(!ch[root][0]){ int oldroot=root; root=ch[root][1]; fa[root]=0; clear(oldroot); return; }else if(!ch[root][1]){ int oldroot=root; root=ch[root][0]; fa[root]=0; clear(oldroot); return; } int leftbig=pre(),oldroot=root; splay(leftbig); ch[root][1]=ch[oldroot][1]; fa[ch[root][1]]=root; clear(oldroot); update(root); } int main() { //freopen("in.txt","r",stdin); int n,a,b; init(); scanf("%d",&n); while(n--){ scanf("%d%d",&a,&b); if(a==1) insert(b); else if(a==2) del(b); else if(a==3) printf("%d\n",find(b)); else if(a==4) printf("%d\n",rank(b)); else if(a==5) { insert(b);printf("%d\n",key[pre()]);del(b); } else if(a==6) { insert(b);printf("%d\n",key[suf()]);del(b); } } return 0; }