鬼子進村[樹狀陣列+二分答案]
阿新 • • 發佈:2018-12-02
[樹狀陣列+二分答案]
如果被封鎖,就在樹狀數組裡插入1
然後每次查詢二分找前面和後面第一個為1的地方就可以了
對於修復,用一個棧維護
複雜度O(nlogn^2)
#include<bits/stdc++.h> #define N 50050 using namespace std; int n,m,c[N],sta[N],top,vis[N]; void Up(int x,int val){for(;x<=n;x+=x&-x)c[x]+=val;} int Q(int x){int ans=0; for(;x;x-=x&-x)ans+=c[x]; return ans;} int Q_l(int x){ int l=0,r=x; while(l<r){ int mid=(l+r)>>1; if(Q(x)-Q(mid)>=1) l=mid+1; else r=mid; }return l; } int Q_r(int x){ int l=x,r=n+1; while(l<r){ int mid=(l+r)>>1; if(Q(mid)-Q(x)>=1) r=mid; else l=mid+1; }return l; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ char s[3]; scanf("%s",s); if(s[0]=='D'){ int x; scanf("%d",&x); Up(x,1); sta[++top]=x , vis[x]=1; } if(s[0]=='R') vis[sta[top]]=0,Up(sta[top--],-1); if(s[0]=='Q'){ int x; scanf("%d",&x); int Left=Q_l(x),Right=Q_r(x); if(vis[x]) printf("0\n"); else printf("%d\n",Right-Left-1); } }return 0; }