您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
标签:span line bzoj include 维护 root 最大 and des
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)
对于操作3,4,5,6每行输出一个数,表示对应答案
#include <cstdio> #define Maxn 1000000 using namespace std; int f[Maxn];//father int ch[Maxn][2];//child ; 0 for left ; 1 for right int key[Maxn];//key int cnt[Maxn];//value int siz[Maxn];//size of subtree int sz,root;//size of tree and root //clear the ndoe void clear(int x) { ch[x][0]=ch[x][1]=f[x]=cnt[x]=key[x]=siz[x]=0; } //rightson return 1;left son return 0 int getson(int x) { return ch[f[x]][1]==x; } //update the size void update(int x) { siz[x]=cnt[x]; if (ch[x][0]) siz[x]+=siz[ch[x][0]]; if (ch[x][1]) siz[x]+=siz[ch[x][1]]; } //retation int rotate(int x) { int fa=f[x],fafa=f[fa],k=getson(x); ch[fa][k]=ch[x][k^1];f[ch[fa][k]]=fa; ch[x][k^1]=fa;f[fa]=x; f[x]=fafa; if (fafa) ch[fafa][ch[fafa][1]==fa]=x; update(fa);update(x); } //rotate until x is the root void splay(int x) { for (int fa;fa=f[x];rotate(x)) if (f[fa]) rotate(getson(x)==getson(fa) ? fa : x); root=x; } int pre() { int now=ch[root][0]; while(ch[now][1]) now=ch[now][1]; return now; } int nex() { int now=ch[root][1]; while(ch[now][0]) now=ch[now][0]; return now; } //find x‘s pos int findpos(int v) { int now=root,ans=0; while(1) { if (v<key[now]) now=ch[now][0]; else { ans+=ch[now][0]?siz[ch[now][0]]:0; if (v==key[now]) { splay(now); return ans+1; } ans+=cnt[now]; now=ch[now][1]; } } } //find pos‘s x int findx(int x) { int now=root; while(1) { if (ch[now][0] && x<=siz[ch[now][0]]) now=ch[now][0]; else { int temp=(ch[now][0]?siz[ch[now][0]]:0)+cnt[now]; if (x<=temp) return key[now]; x-=temp; now=ch[now][1]; } } } //ceate a new splay node void create(int v) { sz++; ch[sz][0]=ch[sz][1]=f[sz]=0; key[sz]=v; cnt[sz]=1; siz[sz]=1; //root=sz; } //insert a node void insert(int v) { if (!root) create(v),root=sz; else { int now=root,fa=0; while(1) { if (key[now]==v) { cnt[now]++; update(now);update(fa); splay(now); break; } fa=now; now=ch[fa][v>key[fa]]; if (!now) { create(v); f[sz]=fa; ch[fa][v>key[fa]]=sz; update(fa); splay(sz); break; } } } } void del(int x) { int t=findpos(x); if (cnt[root]>1) { cnt[root]--; update(root); return; } //none if (!ch[root][0] && !ch[root][1]) { clear(root); root=0; return; } //one if (!ch[root][1]) { int temp=root; root=ch[root][0]; f[root]=0; clear(temp); return; } else if (!ch[root][0]) { int temp=root; root=ch[root][1]; f[root]=0; clear(temp); return; } //two int pre1=pre(),temp=root; splay(pre1); f[ch[temp][1]]=root; ch[root][1]=ch[temp][1]; clear(temp); update(root); } int main() { int n,opt,x; scanf("%d",&n); for (int i=1;i<=n;++i) { scanf("%d%d",&opt,&x); switch(opt) { case 1: insert(x); break; case 2: del(x); break; case 3: printf("%d\n",findpos(x)); break; case 4: printf("%d\n",findx(x)); break; case 5: insert(x); printf("%d\n",key[pre()]); del(x); break; case 6: insert(x); printf("%d\n",key[nex()]); del(x); break; } } }
标签:span line bzoj include 维护 root 最大 and des
原文地址:http://www.cnblogs.com/L-Memory/p/6556921.html