zoukankan      html  css  js  c++  java
  • 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("
    ");
        }
    }
  • 相关阅读:
    GARP和GVRP
    VLAN间路由
    Voice VLAN
    VLAN
    SSH
    Telnet
    FTP
    DHCP
    STP
    交换机
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/3215227.html
Copyright © 2011-2022 走看看