codeforces 374D. Inna and Sequence(特別有意思哈)
阿新 • • 發佈:2018-12-17
題意: 首先給你 n 和 m 然後m 個數,表示位置,這裡首先有一個空的序列 然後n 個操作,如果操作是1 那麼向序列的末尾加1 ,如果操作是0 ,那麼向序列的末尾加0 如果是-1 ,那麼刪除上邊給的m 個位置的數,最後輸出序列。為空輸出。。。
思路: 因為n m都比較大一開始還真不敢想,然後其實可以發現對於每一次-1 操作其實我是可以暴力每一位置然後二分的,首先我如果前一個位置在序列中已經不存在,那麼我可以直接跳出,其次這m個位置各不相同,那麼我該位置的L就可以設為以前一個位置找到的對應位置。然後就暴力二分就可以了。複雜度也不會超的。
程式碼:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1e6+5; // 外掛 1 template <class T> bool scan_d(T &ret) { char c; int sgn; T bit = 0.1; if (c=getchar(), c==EOF) { return 0; } while (c!='-'&& c!='.'&& (c<'0'||c>'9')) { c = getchar(); } sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while (c = getchar(), c >= '0' && c <= '9') { ret = ret * 10 + (c - '0'); } if (c == ' ' || c == '\n') { ret *= sgn; return 1; } while (c = getchar(), c >= '0' && c <= '9') { ret += (c - '0') * bit, bit /= 10; } ret *= sgn; return 1; } template <class T> inline void print_d(T& x) { if (x > 9) { print_d(x/10); } putchar(x % 10 + '0'); } int n,m; int a[N]; int c[N]; int val[N]; int pos[N]; int vis[N]; int tot=0; int lowbit(int x) { return x&(-x); } void update(int x,int num) { for(;x<=n+2;x+=lowbit(x)) { c[x]+=num; } } int query(int x) { int sum=0; for(;x>0;x-=lowbit(x)) { sum+=c[x]; } return sum; } int jud(int x,int aim) { int sum=query(x); if(sum>=aim) return 1; return 0; } int main() { scanf("%d %d",&n,&m); for(int i=1;i<=m;i++) { scan_d(a[i]); } int op; int tmpn=n; while(tmpn--) { scan_d(op); if(op==0) { ++tot; update(tot,1); val[tot]=0; } else if(op==1) { ++tot; update(tot,1); val[tot]=1; } else { int l,r,in,mid; int pre=1; for(int p=1;p<=m;p++) { in=-1; l=pre; r=tot; while(l<=r) { mid=(l+r)>>1; if(jud(mid,a[p])) { in=mid; r=mid-1; } else l=mid+1; } pos[p]=in; pre=in; if(in==-1) break; } for(int p=1;p<=m;p++) { if(pos[p]==-1) break; update(pos[p],-1); vis[pos[p]]=1; } } } int f=0; for(int i=1;i<=tot;i++) { if(vis[i]) continue; f=1; printf("%d",val[i]); } if(f==0) { printf("Poor stack!\n"); } return 0; }