hdu 4614 线段树

思路:当k为1的时候,用二分法查询包含有f个空瓶的上界r,然后更新会方便很多,直接更新区间(a,r)了。

#include<iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<cmath>

#define lson(x) (x<<1)

#define rson(x) ((x<<1)+1)

#define mid ((tree[po].l+tree[po].r)>>1)

#define inf 1<<30

#define Maxm 1000000

#define Maxn 60000

using namespace std;

struct Tree{

    int l,r,left,up;

}tree[Maxm];

int flag=0,ans,fir;

void buildTree(int l,int r,int po)

{

    tree[po].l=l,tree[po].r=r;

    tree[po].left=r-l+1;

    tree[po].up=0;

    if(l==r)

        return ;

    buildTree(l,mid,lson(po));

    buildTree(mid+1,r,rson(po));

}

void down(int po)

{



    if(!tree[po].left)

    {

        tree[po].up=0;

        tree[lson(po)].left=0;

        tree[rson(po)].left=0;

        tree[rson(po)].up=0;

        tree[lson(po)].up=0;

        return ;

    }

    if(!tree[po].up) return ;

    tree[lson(po)].left=mid-tree[po].l+1;

    tree[rson(po)].left=tree[po].r-mid;

    tree[rson(po)].up=1;

    tree[lson(po)].up=1;

    tree[po].up=0;

}

void update(int l,int r,int po)

{

    if(l<=tree[po].l&&r>=tree[po].r)

    {

        ans+=tree[po].r-tree[po].l+1-tree[po].left;

        tree[po].left=tree[po].r-tree[po].l+1;

        tree[po].up=1;

        return ;

    }

    down(po);

    if(r<=mid)

        update(l,r,lson(po));

    else

        if(l>mid)

        update(l,r,rson(po));

    else{

        update(l,r,lson(po));

        update(l,r,rson(po));

    }

    tree[po].left=tree[lson(po)].left+tree[rson(po)].left;

}

int findTree(int l,int r,int po)

{

    if(l<=tree[po].l&&r>=tree[po].r)

    {

        return tree[po].left;

    }

    down(po);

    int temp=0;

    if(r<=mid)

        temp=findTree(l,r,lson(po));

    else

        if(l>mid)

        temp=findTree(l,r,rson(po));

    else{

        temp=findTree(l,r,lson(po));

        temp+=findTree(l,r,rson(po));

    }

    tree[po].left=tree[lson(po)].left+tree[rson(po)].left;

    return temp;

}

void Insert(int l,int r,int po)

{

    if(l<=tree[po].l&&r>=tree[po].r)

    {

        if(tree[po].left==tree[po].r-tree[po].l+1&&!flag)

            flag=1,fir=tree[po].l;

        if(flag)

        {

            tree[po].left=0;

            return ;

        }

    }

    if(!tree[po].left)

        return ;

    down(po);

    if(r<=mid)

        Insert(l,r,lson(po));

    else

        if(l>mid)

        Insert(l,r,rson(po));

    else{

        Insert(l,r,lson(po));

        Insert(l,r,rson(po));

    }

    tree[po].left=tree[lson(po)].left+tree[rson(po)].left;

}

int main()

{

    int n,m,k,a,b,i,j,t;

    scanf("%d",&t);

    while(t--)

    {

        scanf("%d%d",&n,&m);

        buildTree(0,n-1,1);

        for(i=1;i<=m;i++)

        {

            scanf("%d%d%d",&k,&a,&b);

            if(k==1)

            {

                flag=0;

                int l,r,Mid,temp;

                temp=findTree(a,n-1,1);

                if(temp<b)

                    b=temp;

                l=a,r=n-1;

                while(r>l)

                {

                    Mid=(l+r)>>1;

                    temp=findTree(a,Mid,1);

                    if(temp>=b)

                        r=Mid;

                    else

                        l=Mid+1;

                }

                Insert(a,r,1);

                if(!flag)

                    printf("Can not put any one.\n");

                else

                    printf("%d %d\n",fir,r);

            }

            else

            {

                ans=0;

                update(a,b,1);

                printf("%d\n",ans);

            }

        }

        printf("\n");

    }

    return 0;

}

 

你可能感兴趣的:(HDU)