1. 程式人生 > >Codeforces Round #220 (Div. 2)D. Inna and Sequence 樹狀數組+二分

Codeforces Round #220 (Div. 2)D. Inna and Sequence 樹狀數組+二分

cto cout ret 標記 unsigned bound roo div sign

題目鏈接:D. Inna and Sequence

題意:三種操作,1往序列後面加個1,0往序列後面加個0,-1,把給定位置上的數刪除。

題解:用樹狀數組保存的數沒被刪的個數,每次二分找到位置,然後用數組標記這裏被刪除。

#include<bits/stdc++.h>
#include<set>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#define pb push_back
#define ll long long
#define
PI 3.14159265 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define eps 1e-7 typedef unsigned long long ull; const int mod=1e9+9; const int inf=0x3f3f3f3f; const int maxn=1e6+5; const int root=1e6+7; using namespace std; ll t,n,m,k,len; int tot,ed; int a[maxn],b[maxn],v[maxn];
int p[maxn]; vector<int>st; int lowbit(int x) { return x&(-x); } void add(int x,int y) { for(int i=x;i<maxn;i+=lowbit(i)) { b[i]+=y; } } int get_sum(int x) { int ans=0; while(x>0) { ans+=b[x]; x-=lowbit(x); }
return ans; } int sec(int x) { int l=1,r=ed; while(l<=r) { int mid=(l+r)>>1; if(get_sum(mid)>=x)r=mid-1; else l=mid+1; } return l; } void view() { for(int i=1;i<=ed;i++) { if(!v[i])cout<<a[i]; } cout<<endl; } int main() { ios::sync_with_stdio(false); cin.tie(0); cin>>n>>m; for(int i=0;i<m;i++) { cin>>p[i]; } int op; while(n--) { cin>>op; if(op==1) { ++tot; a[++ed]=1; add(ed,1); } else if(op==0) { ++tot; ++ed; add(ed,1); } else { if(tot<=0)continue; int pp=lower_bound(p,p+m,tot)-p; if(p[pp]==tot)pp++; for(int i=0;i<pp;i++) { int l=sec(p[i]); st.pb(l); tot--; v[l]=true; } for(int i=0;i<st.size();i++) { add(st[i],-1); } st.clear(); } // view(); } if(tot>0) { view(); } else{ cout<<"Poor stack!"<<endl; } return 0; }

Codeforces Round #220 (Div. 2)D. Inna and Sequence 樹狀數組+二分