【刷题】【树状数组】会场预约

 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
",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
",cnt);
            add(ql,1);
            rt[ql]=qr;
            sum=sum-cnt+1;
        }
        //我们只统计l的个数,right就用rt[l]就好 
        //找到起始点在0-r之间,终止点在l之后的区间,cnt++
        //然后去掉
        //直到最右边的rt<l,就退出 
    }
    
    return 0;
}
原文地址:https://www.cnblogs.com/xwww666666/p/11727482.html