HDU 5372 Segment Game(BIT)

Description
在x轴上进行两种操作
0 a:表示插入线段[a,a+i],其中i是该操作的次数
1 a:表示删除第a次放置的线段(保证删除合法)
每次放完一个线段后,问被这个线段完全包含的线段数量
Input
多组用例,每组用例第一行一整数n表示操作次数,之后n行每行两个整数a和b表示一次操作,以文件尾结束输入(1<=n<=200000,sum(n)<=700000,|b|< 10^9)
Output
对于每组用例,在每次插入操作时输出被当前线段包含的线段数量
Sample Input
3
0 0
0 3
0 1
5
0 1
0 0
1 1
0 1
0 0
Sample Output
Case #1:
0
0
0
Case #2:
0
1
0
2
Solution
由于当前放置的线段[l,r]一定是x轴现有线段中最长的,所以被包含的线段满足必然是右端点不大于r且左端点不小于l的,那么我们用两个树状数组分别统计左端点小于l的线段数量cnt1以及右端点小于等于r的线段树良cnt2,则cnt2-cnt1即为答案,时间复杂度O(nlogn),注意区间端点过大需要离散化一下
Code

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 222222
struct BIT 
{
    #define lowbit(x) (x&(-x))
    int b[maxn];
    void init()
    {
        memset(b,0,sizeof(b));
    }
    void add(int x,int v)
    {
        while(x<maxn)
        {
            b[x]+=v;
            x+=lowbit(x);
        }
    }
    int sum(int x)
    {
        int ans=0;
        while(x)
        {
            ans+=b[x];
            x-=lowbit(x);
        }
        return ans;
    }
};
BIT L,R;
int n,res=1,q[maxn],a[maxn],b[maxn],pos[maxn],l[maxn],r[maxn],len,cnt1,cnt2;
int main()
{
    while(~scanf("%d",&n))
    {
        L.init(),R.init();
        len=1,cnt1=cnt2=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&q[i],&l[i]);
            if(!q[i])
            {
                r[i]=l[i]+len;
                pos[len++]=i;
                a[cnt1++]=l[i],b[cnt2++]=r[i];
            }
        }
        sort(a,a+cnt1),sort(b,b+cnt2);
        cnt1=unique(a,a+cnt1)-a;
        cnt2=unique(b,b+cnt2)-b;
        printf("Case #%d:\n",res++);
        for(int i=1;i<=n;i++)
        {
            if(q[i])
            {
                int temp=pos[l[i]];
                int tl=lower_bound(a,a+cnt1,l[temp])-a+1;
                int tr=lower_bound(b,b+cnt2,r[temp])-b+1;
                L.add(tl,-1),R.add(tr,-1);
            }
            else
            {
                int tl=lower_bound(a,a+cnt1,l[i])-a+1;
                int tr=lower_bound(b,b+cnt2,r[i])-b+1;
                int ans=R.sum(tr)-L.sum(tl-1);
                L.add(tl,1),R.add(tr,1);
                printf("%d\n",ans);
            }
        }
    }
    return 0;
}

你可能感兴趣的:(HDU 5372 Segment Game(BIT))