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 }