hdu 4614 (线段树)

题目

两种操作:

1 x y: 从x开始放,输出能放的起始位置,输出放的最后位置,不一定y朵花都有位置放!如果一朵也不能放,就输出....

2 x y:  清空操作,[x,y];


用1表示此花瓶是空的,那我们就是要查找某区间的和,清空操作就是区间全部变为1!

至于放花操作,我们首先需要找出x开始的第一个空花瓶,这个可以利用二分,

                            而找最后一个花瓶也要二分,查找一个点,使起点到这个点的区间和,尽可能的接近我们需要的值。


#include
#include
#include
using namespace std;
#define N 50010
struct node
{
    int r,l;
    int lazy,num;
}root[N*4];
inline void Pushup(int t)
{
    root[t].num=root[t*2].num+root[t*2+1].num;
}
inline void pushdown(int t)
{
    if(root[t].lazy!=-1)
    {
        root[t*2].lazy=root[t*2+1].lazy=root[t].lazy;
        root[t*2].num=root[t*2].lazy*(root[t*2].r-root[t*2].l+1);
        root[t*2+1].num=root[t*2+1].lazy*(root[t*2+1].r-root[t*2+1].l+1);
        root[t].lazy=-1;
    }
}
inline void build(int t,int x,int y)
{
    root[t].l=x;
    root[t].r=y;
    root[t].num=(y-x+1);
    root[t].lazy=-1;
    if(x==y) return;
    int m=(x+y)>>1;
    build(t*2,x,m);
    build(t*2+1,m+1,y);
}
inline void Modefiy(int t,int x,int y,int val)
{
    int l=root[t].l;
    int r=root[t].r;
    if(l==x&&r==y)
    {
        root[t].lazy=val;
        root[t].num=val*(r-l+1);
        return;
    }
    pushdown(t);
    int m=(l+r)>>1;
    if(x<=m)  Modefiy(t*2,x,min(y,m),val);
    if(y>m)   Modefiy(t*2+1,max(x,m+1),y,val);
    Pushup(t);
}
inline int query(int t,int x,int y)
{
    int l=root[t].l;
    int r=root[t].r;
    if(l==x&&r==y)
    {
        return root[t].num;
    }
    pushdown(t);
    int m=(l+r)>>1;
    int ans=0;
    if(x<=m) ans+=query(t*2,x,min(m,y));
    if(y>m) ans+=query(t*2+1,max(x,m+1),y);
    return ans;
}

int main()
{
    int ta;
    scanf("%d",&ta);
    for(int ca=1;ca<=ta;ca++)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        build(1,1,n);
        for(int i=1;i<=m;i++)
        {
            int op,x,y;
            scanf("%d%d%d",&op,&x,&y);
            if(op==2)
            {
                x++,y++;
                printf("%d\n",y-x+1-query(1,x,y));
                Modefiy(1,x,y,1);
            }
            else
            {
                x++;
                if(query(1,x,n)==0)
                {
                    puts("Can not put any one.");
                }
                else
                {
                    int s=x,t=n;
                    int mi=n+1,m;
                    while(s<=t)
                    {
                        m=(s+t)>>1;
                        if(query(1,s,m)>=1)
                        {
                            mi=min(mi,m);
                            t=m-1;
                        }
                        else s=m+1;
                    }
                    s=mi;
                    t=n;
                    int temp=query(1,s,n);
                    if(temp>1;
                        int p=query(1,mi,m);
                        if(p==y)
                        {
                            mx=min(mx,m);
                            t=m-1;
                        }
                        else if(p>y) t=m-1;
                        else s=m+1; 
                    }
                    printf("%d %d\n",mi-1,mx-1);
                    Modefiy(1,mi,mx,0);
                }
            }
        }
        printf("\n");
    }
}


你可能感兴趣的:(ACM)