【刷题】【树状数组】会场预约
A操作:有一个新的预约是从“start日”到“end日”,并且拒绝掉所有与它相冲突的预约。
执行这个操作的时候,你的系统应当返回为了这个新预约而拒绝掉的预约个数,以方便QQ与自己的记录相校对。
B操作:请你的系统返回当前的仍然有效的预约的总数。
#include<cstdio> #include<cstdlib> #include<cstring> using namespace std; int n;char ch[10]; const int N=100003,mx=100000; int tr[N],rt[N]; int lowbit(int x) { return x&(-x); } void add(int pos,int v) { while(pos<=mx) tr[pos]+=v,pos+=lowbit(pos); } int query(int pos) { int as=0; while(pos>0) as+=tr[pos],pos-=lowbit(pos); return as; } int main() { scanf("%d",&n); int sum=0; memset(rt,-1,sizeof(rt)); while(n--) { scanf("%s",ch); if(ch[0]=='B') printf("%d\n",sum); else { int ql,qr,l,r; scanf("%d%d",&ql,&qr); l=0,r=qr; int sm,cnt=0; while(1) { sm=query(r); while(l<r) { int mid=(l+r)>>1; if(query(mid)<sm) l=mid+1; else r=mid; } if(rt[l]<ql) break; add(l,-1),cnt++; r=l-1,l=0; } printf("%d\n",cnt); add(ql,1); rt[ql]=qr; sum=sum-cnt+1; } //我们只统计l的个数,right就用rt[l]就好 //找到起始点在0-r之间,终止点在l之后的区间,cnt++ //然后去掉 //直到最右边的rt<l,就退出 } return 0; }