HDU4614

题目大意

给定一个区间[0,N-1],初始时每个位置上的数字都是0,可以对其进行以下两种操作:

1、在位置A开始寻找F(如果没有这么多,则有多少个就找多少个)个数值为0的位置,把位置上的数修改为1,并返回第一个和最后一个修改的位置

2、查询区间[a,b]内1的个数,并把区间[a,b]每个位置上的数修改为0

题解

基础的线段树~~~第一个操作可以用二分求出始末位置,然后进行区间修改,第二问就是区间查询和区间修改

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 50005
#define lson l,m,s<<1
#define rson m+1,r, s<<1|1
int msum[MAXN<<2],setv[MAXN<<2],sumv[MAXN<<2];
void PushUp(int s,int m)
{
    msum[s]=msum[s<<1]+msum[s<<1|1];
    sumv[s]=sumv[s<<1]+sumv[s<<1|1];
}
void PushDown(int s,int m)
{
    if(setv[s]!=-1)
    {
        setv[s<<1]=setv[s<<1|1]=setv[s];
        msum[s<<1]=setv[s]?(m-(m>>1)):0;
        msum[s<<1|1]=setv[s]?(m>>1):0;
        sumv[s<<1]=setv[s]?0:(m-(m>>1));
        sumv[s<<1|1]=setv[s]?0:(m>>1);
        setv[s]=-1;
    }
}
void build(int l,int r,int s)
{
    msum[s]=r-l+1,setv[s]=-1,sumv[s]=0;
    if(l==r) return;
    int m=(l+r)>>1;
    build(lson);
    build(rson);
}
int query(int ql,int qr,int l,int r,int s,int p)
{
    if(ql<=l&&r<=qr)
    {
        if(p==1)
            return sumv[s];
        else
            return msum[s];
    }
    PushDown(s,r-l+1);
    int m=(l+r)>>1,ans=0;
    if(ql<=m) ans+=query(ql,qr,lson,p);
    if(qr>m) ans+=query(ql,qr,rson,p);
    return ans;
}
void update(int ql,int qr,int l,int r,int s,int d)
{
    if(ql<=l&&r<=qr)
    {
        msum[s]=d?r-l+1:0;
        sumv[s]=d?0:r-l+1;
        setv[s]=d;
        return;
    }
    PushDown(s,r-l+1);
    int m=(l+r)>>1;
    if(ql<=m) update(ql,qr,lson,d);
    if(qr>m) update(ql,qr,rson,d);
    PushUp(s,r-l+1);
}
int main(void)
{
    int T,m,n,a,b,k,ll,rr;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        build(0,n-1,1);
        while(m--)
        {
            int t;
            scanf("%d%d%d",&k,&a,&b);
            if(k==1)
            {
                t=query(a,n-1,0,n-1,1,2);
                if(t==0) printf("Can not put any one.
");
                else
                {
                    if(t<b) b=t;
                    int l,r,mid,ans;
                    if(a-1>=0) ans=query(0,a-1,0,n-1,1,2);
                    else
                        ans=0;
                    l=a;
                    r=n-1;
                    while(l<=r)
                    {
                        mid=(l+r)>>1;
                        if(query(0,mid,0,n-1,1,2)-ans>=1)
                            r=mid-1;
                        else
                            l=mid+1;
                    }
                    ll=l;
                    l=a;
                    r=n-1;
                    while(l<=r)
                    {
                        mid=(l+r)>>1;
                        if(query(0,mid,0,n-1,1,2)-ans>=b)
                            r=mid-1;
                        else
                            l=mid+1;
                    }
                    rr=l;
                    printf("%d %d
",ll,rr);
                    update(ll,rr,0,n-1,1,0);
                }
            }
            else
            {
                printf("%d
",query(a,b,0,n-1,1,1));
                update(a,b,0,n-1,1,1);
            }
        }
        printf("
");
    }
}
原文地址:https://www.cnblogs.com/zjbztianya/p/3215227.html