問題 D(1194): 【基礎算法】黑匣子
時間限制: 1 Sec 內存限制: 64 MB提交: 94 解決: 58
[提交][狀態][我的提交]
題目描述
我們使用黑匣子的一個簡單模型。它能存放一個整數序列和一個特定的變量i。初始時刻,黑匣子爲空且i爲0。這個黑匣子能執行兩類命令:
ADD x:把元素x放入黑匣子中(x的絕對值不超過2000000);
GET :先將黑匣子中的i的值加1,然後輸出黑匣子中所有數中第i小的數(注意:這裏第i小的數是指將黑匣子中所有的數由小到大排序後第i個位置的數);
現在給處N條ADD和M條GET命令,要求你輸出每條GET命令執行後的值。
例如N=7 M=4的一個例子:
輸入
第一行兩個整數N,M(M<N≤30000),表示ADD命令和GET命令的條數;
第二行:N個空格分開的整數,依次表示N次ADD命令的元素
第三行:M個空格分開的整數,依次表示M次GET命令在第幾次ADD命令之後
輸出
有M行,每行對應一條GET命令的輸出結果
樣例輸入
(如果複製到控制檯無換行,可以先粘貼到文本編輯器,再複製)
7 4
3 1 -4 2 8 -1000 2
1 2 6 6
樣例輸出
3
3
1
2
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
int n,m,num,sum1,sum2,reout,now=1;
int small[300010],big[300010],op[300010];
void build_small(int x,int m){
int np;
while(1){
np=x*2;
if(np>m) break ;
if(np+1<=m&&small[np+1]<small[np]) np++;
if(small[x]<small[np]) break ;
swap(small[x],small[np]);
x=np;
}
}
void build_big(int x,int m){
int np;
while(1){
np=x*2;
if(np>m) break ;
if(np+1<=m&&big[np+1]>big[np]) np++;
if(big[x]>big[np]) break ;
swap(big[x],big[np]);
x=np;
}
}
void up_build_small(int x,int m){
int np;//根
while(1){
np=x/2;
if(np<m) break ;
if(small[x]>small[np]) break ;
swap(small[np],small[x]);
x=np;
}
}
void up_build_big(int x,int m){
int np;
while(1){
np=x/2;
if(np<m) break ;
if(big[np]>big[x]) break ;
swap(big[np],big[x]);
x=np;
}
}
void putin_small(int x){
small[++sum1]=x;
if(sum1<=1) return ;
up_build_small(sum1,1);
}
void putin_big(int x){
big[++sum2]=x;
if(sum2<=1) return ;
up_build_big(sum2,1);
}
void popout_big(){
swap(big[1],big[sum2]);
build_big(1,--sum2);
}
void popout_small(){
swap(small[1],small[sum1]);
build_small(1,--sum1);
}
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&op[i]);
for(int out=1;out<=m;out++){
scanf("%d",&num);
for(now=now;now<=num;now++){
if(op[now]>big[1]||!sum2)
putin_small(op[now]);
else{
putin_small(big[1]);
popout_big();
putin_big(op[now]);
}
}
for(int i=1;i<=out-reout;i++){
if(i==out-reout)
printf("%d\n",small[1]);
putin_big(small[1]);
popout_small();
reout++;
}
}
return 0;
}