COGS 723. [SDOI2007] 超级数组

                  ★★☆   输入文件:arr.in   输出文件:arr.out   简单对比
                      时间限制:1 s   内存限制:3 MB

                      Source: SDOI2007 Day2
【问题描述】

一般的数组大家都经常使用,相信很多同学没有见过下面的超级数组。

超级数组存储的是一些正整数,它还支持下面的两个操作

(1)、插入一个元素,命令是 "i key" 。 key 是要插入的数。

(2)、输出第 k 大元素并删除该元素,命令是 "d k"。输出第 k 大元素并删除它。

“第 k 大”是指:现有的数中,如果从小到大排好序,从最小的开始作为第一大算起,

一直数到第 k 个。

现在给出一个开始是空的超级数组,请维护好该数组

【输入】(arr.in)

第一行 n、m:n<=1 000 000 000 , m<=100 000。表示插入数的范围是 1 至n ,共有m 条命令(包括插入和删除)。

以下 m 行,每行一条命令,如题中描述。每条命令中字母和后面的数字之间一个空格。

保证输入数据是正确的,删除的数一定存在。

【输出】(arr.out)

对于每个删除命令,按删除命令顺序输出删除的数,每个数一行

【样例输入】

100 10

i 57

i 99

i 65

d 3

i 89

d 2

d 2

d 1

i 93

i 29

【样例输出】

99

65

89

57

SBT模板题。。。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<algorithm>
  5 #include<cmath>
  6 #include<cstring>
  7 #include<queue>
  8 #include<vector>
  9 using namespace std;
 10 const int maxn=100001;
 11 int key[maxn],siz[maxn],lc[maxn],rc[maxn];
 12 int root,tot;
 13 int N,M;
 14 char s[5];
 15 void r_rotate(int &rt){
 16     int k=lc[rt];
 17     lc[rt]=rc[k];
 18     rc[k]=rt;
 19     siz[k]=siz[rt];
 20     siz[rt]=siz[lc[rt]]+siz[rc[rt]]+1;
 21     rt=k;
 22 }
 23 void l_rotate(int &rt){
 24     int k=rc[rt];
 25     rc[rt]=lc[k];
 26     lc[k]=rt;
 27     siz[k]=siz[rt];
 28     siz[rt]=siz[lc[rt]]+siz[rc[rt]]+1;
 29     rt=k;
 30 }
 31 void Maintain(int &rt,bool flag){
 32     if(flag==false){
 33         if(siz[lc[lc[rt]]]>siz[rc[rt]]) r_rotate(rt);
 34         else if(siz[rc[lc[rt]]]>siz[rc[rt]]){
 35             l_rotate(lc[rt]);
 36             r_rotate(rt);
 37         }
 38         else return ;
 39     }
 40     else{
 41         if(siz[rc[rc[rt]]]>siz[lc[rt]]) l_rotate(rt);
 42         else if(siz[lc[rc[rt]]]>siz[lc[rt]]){
 43             r_rotate(rc[rt]);
 44             l_rotate(rt);
 45         }
 46         else return ;
 47     }
 48     Maintain(lc[rt],false); Maintain(rc[rt],true);
 49     Maintain(rt,false); Maintain(rt,true);
 50 }
 51 void insert(int &rt,int v){
 52     if(rt==0){
 53         rt=++tot;
 54         key[rt]=v;
 55         siz[rt]=1; lc[rt]=rc[rt]=0;
 56         return ;
 57     }
 58     siz[rt]++;
 59     if(v<=key[rt]) insert(lc[rt],v);
 60     else insert(rc[rt],v);
 61     Maintain(rt,false); Maintain(rt,true);
 62 }
 63 int Delete(int &rt,int v){
 64     int ans;
 65     siz[rt]--;
 66     if(v==key[rt]||(v<key[rt]&&lc[rt]==0)||(v>key[rt]&&rc[rt]==0)){
 67         ans=key[rt];
 68         if(lc[rt]==0||rc[rt]==0) rt=lc[rt]+rc[rt];
 69         else key[rt]=Delete(lc[rt],key[rt]+1);
 70         return ans;
 71     }
 72     if(v<key[rt]) ans=Delete(lc[rt],v);
 73     else ans=Delete(rc[rt],v);
 74     return ans;
 75 }
 76 bool find(int &rt,int v){
 77     if(rt==0) return false;
 78     if(v==key[rt]) return true;
 79     if(v<key[rt]) return find(lc[rt],v);
 80     if(v>key[rt]) return find(rc[rt],v);
 81 }
 82 int select(int &rt,int v){
 83     if(v==siz[lc[rt]]+1) return key[rt];
 84     else if(v<siz[lc[rt]]+1) return select(lc[rt],v);
 85     else return select(rc[rt],v-siz[lc[rt]]-1);
 86 }
 87 int main(){
 88     freopen("arr.in","r",stdin);
 89     freopen("arr.out","w",stdout);
 90     scanf("%d%d",&N,&M);
 91     for(int i=1,tmp;i<=M;i++){
 92         scanf("%s%d",s,&tmp);
 93         if(s[0]=='i') insert(root,tmp);
 94         else{
 95             int ans=select(root,tmp);
 96             printf("%d\n",ans);
 97             Delete(root,ans);
 98         }
 99     }
100     return 0;
101 }
posted @ 2016-01-15 19:03  CXCXCXC  阅读(167)  评论(0编辑  收藏  举报