问题 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;
}