Inna and Sequence

时间:2020-12-03 07:43:15

Codeforces Round #220 (Div. 2) D:http://codeforces.com/contest/374/problem/D

题意:给你m个数,这m个数是递增的。然后给你n个操作,每个操作是一个数1,0,-1,如果是1或者0,就把这个数数直接放在序列的末位,刚开始的时候,序列为空。当操作数是-1的时候,只要把ai<=当期序列长度,就把ai所对应的那一位删除。

题解:用树状数组和二分搞。首先如果是0或者1,直接把这个数放进去,把这个数的位子加一。然后更新的时候,首先查询到小于等于序列长度的那些数,表示要删除在该序列的第几个数,然后用二分找到这个数,但是这里不能直接删除,要先保存,然后等所有的数都找完了,再进行统一删除。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e6+;
int c[N],a[N],ans[N],top,as[N];
int n,m,sum;
void init(){
memset(c,,sizeof(c));
memset(a,,sizeof(a));
memset(ans,-,sizeof(ans));
top=;
}
int lowbit(int x){
return x&(-x); }
void add(int x,int val){
while(x<=m){
c[x]+=val;
x+=lowbit(x);
}
} int getsum(int x){
int ans=;
while(x){
ans+=c[x];
x-=lowbit(x);
}
return ans;
}
void work(int num,int ct){
int l=,r=m;
while(l<r){
int mid=(l+r)/;
//printf("%d\n",mid);
if(getsum(mid)>=num)r=mid;
else
l=mid+;
}
as[ct]=l;
}
int t;
int main(){
while(~scanf("%d%d",&m,&n)){
init();
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=;i<=m;i++){
scanf("%d",&t);
if(t==||t==){
ans[++top]=t;
sum++;
add(top,);
}
else{
int temp=lower_bound(a+,a+n+,sum)-a;
if(temp>n)temp--;
else if(a[temp]>sum)temp--;
sum-=temp;
// printf("%d\n",temp);
for(int i=;i<=temp;i++)
work(a[i],i);
for(int i=;i<=temp;i++){
add(as[i],-);
ans[as[i]]=-;
}
} }
bool flag=false;
for(int i=;i<=m;i++){
if(ans[i]==-)continue;
printf("%d",ans[i]);
flag=true;
}
if(!flag)printf("Poor stack!");
puts(""); }
}