HDU 4614 二分加线段树

来源:互联网 发布:2016中国经济数据公布 编辑:程序博客网 时间:2024/05/16 15:11

【题意】初始有n个空花瓶,然后有q个操作,1 x y,从x开始插花,插够k个即可。2 x y,把x,y区间有有花的花瓶全部清空。

【解题方法】

线段树维护剩余空花瓶的个数

第一种操作二分≥1的最左边的位置,二分≥k的最左边位置
第二种直接更新就好啦
复杂度是O(n+mlog2n)


【AC代码】


#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn=5e5+5;int n;struct Segment{    int sum[maxn<<2],lazy[maxn<<2];    void Build(int l,int r,int rt)    {        sum[rt]=r-l+1;        lazy[rt]=-1;        if(l==r) return ;        int mid=(l+r)/2;        Build(l,mid,rt*2);        Build(mid+1,r,rt*2+1);    }    void pushup(int rt){        sum[rt]=sum[rt*2]+sum[rt*2+1];    }    void pushdown(int rt,int m){        if(lazy[rt]!=-1){            lazy[rt*2]=lazy[rt*2+1]=lazy[rt];            sum[rt*2]=lazy[rt]*(m-(m>>1));            sum[rt*2+1]=lazy[rt]*(m>>1);            lazy[rt]=-1;        }    }    int update(int L,int R,int v,int l,int r,int rt)    {        if(L<=l&&r<=R){            int ret=sum[rt];            sum[rt]=v*(r-l+1);            lazy[rt]=v;            return ret;        }        int mid=(l+r)/2;        pushdown(rt,r-l+1);        int ret=0;        if(L<=mid) ret+=update(L,R,v,l,mid,rt*2);        if(mid<R)  ret+=update(L,R,v,mid+1,r,rt*2+1);        pushup(rt);        return ret;    }    int queryans(int L,int R,int l,int r,int rt)    {        if(L<=l&&r<=R){            return sum[rt];        }        pushdown(rt,r-l+1);        int ret=0;        int mid=(l+r)/2;        if(L<=mid) ret+=queryans(L,R,l,mid,rt*2);        if(mid<R)  ret+=queryans(L,R,mid+1,r,rt*2+1);        return ret;    }}Tree;int get(int st,int k){    int l=st,r=n;    while(l<=r){        int m=(l+r)/2;        if(Tree.queryans(st,m,1,n,1)>=k) r=m-1;        else l=m+1;    }    return l;}int main(){    int T,q;    scanf("%d",&T);    while(T--)    {        int op,x,y;        scanf("%d%d",&n,&q);        Tree.Build(1,n,1);        while(q--)        {            scanf("%d%d%d",&op,&x,&y);            if(op==1){                int all=Tree.queryans(x+1,n,1,n,1);                if(all==0){                    puts("Can not put any one.");                }                else{                    int l=get(x+1,1);                    int r=get(x+1,min(all,y));                    //cout<<l<<" "<<r<<endl;                    Tree.update(l,r,0,1,n,1);                    printf("%d %d\n",l-1,r-1);                }            }else{                int tt=Tree.update(x+1,y+1,1,1,n,1);                int ans=y-x+1-tt;                printf("%d\n",ans);            }        }        printf("\n");    }    return 0;}



0 0