思路:
树状数组+二分
因为被删的点最多N=1e6个,所以复杂度N*logN*logN
前段时间做过一道一样的题,这类题基本套路二分找没删除前的位置
代码:
#include<bits/stdc++.h> using namespace std; #define ll long long #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) const int N=1e6+5; int n; int bit[N]; int a[N]; int ans[N]; bool vis[N]; vector<int>v; void add(int x,int a){ while(x<=1e6)bit[x]+=a,x+=x&-x; } int sum(int x){ int ans=0; while(x)ans+=bit[x],x-=x&-x; return ans; } int srch(int t){ int l=1,r=1e6,mid=(l+r)>>1; while(l<r){ if(sum(mid)>=t)r=mid; else l=mid+1; mid=(l+r)>>1; } return mid; } int main(){ ios::sync_with_stdio(false); cin.tie(0); for(int i=1;i<=1e6;i++)add(i,1); int cnt=0,t,m; cin>>n>>m; for(int i=0;i<m;i++)cin>>a[i]; for(int i=0;i<n;i++){ cin>>t; if(t==-1){ v.clear(); for(int j=0;j<m;j++){ int l=srch(a[j]); if(l>cnt)break; v.pb(l); } for(int j=0;j<v.size();j++){ vis[v[j]]=true; add(v[j],-1); } } else{ ans[++cnt]=t; } } if(sum(cnt)==0)cout<<"Poor stack!"<<endl; else{ for(int i=1;i<=cnt;i++)if(!vis[i])cout<<ans[i]; cout<<endl; } return 0; }