hdu 4614 Vases and Flowers

来源:互联网 发布:3d算法入门 编辑:程序博客网 时间:2024/05/20 06:29

题意:给定一个区间[0,N-1],初始时每个位置上的数字都是0,有两种操作,1.在位置A开始寻找F(如果没有这么多,则有多少个就找多少个)个数值为0的位置,把位置上的数修改为1,并返回第一个和最后一个修改的位置。2.查询区间[A,B]内1的个数,并把区间[A,B]每个位置上的数修改为0。

        对于操作2,直接应用区间更新的懒操作就可以了,而对于操作1,我们可以查询上区间[0,A-1]里有多少有值为0的数,定义其为cnt,然后在整个线段树里查询cnt+1个值为0的数在哪里,同理查询cnt+F个空的瓶子在哪里,这就得到了其对应的起点和终点了。

#include <iostream>#include <cstdio>#include <cstring>using namespace std;#define LL(x) (x<<1)#define RR(x) (x<<1|1)#define MID(a,b) (a+((b-a)>>1))const int N=60005;struct node{    int lft,rht;    int cnt,delay;    int mid(){return MID(lft,rht);}    void fun(int valu)    {        delay=valu;        if(valu>0) cnt=0;        else cnt=rht-lft+1;    }    void init(){ cnt=rht-lft+1; delay=0; }};struct Segtree{    node tree[N*4];    void PushDown(int ind)    {        if(tree[ind].delay)        {            tree[LL(ind)].fun(tree[ind].delay);            tree[RR(ind)].fun(tree[ind].delay);            tree[ind].delay=0;        }    }    void PushUp(int ind)    {        tree[ind].cnt=tree[LL(ind)].cnt+tree[RR(ind)].cnt;    }    void build(int lft,int rht,int ind)    {        tree[ind].lft=lft;    tree[ind].rht=rht;        tree[ind].init();        if(lft!=rht)        {            int mid=tree[ind].mid();            build(lft,mid,LL(ind));            build(mid+1,rht,RR(ind));        }    }    void updata(int st,int ed,int valu,int ind)    {        int lft=tree[ind].lft,rht=tree[ind].rht;        if(st<=lft&&rht<=ed) tree[ind].fun(valu);        else        {            PushDown(ind);            int mid=tree[ind].mid();            if(st<=mid) updata(st,ed,valu,LL(ind));            if(ed> mid) updata(st,ed,valu,RR(ind));            PushUp(ind);        }    }    int query(int st,int ed,int ind)    {        int lft=tree[ind].lft,rht=tree[ind].rht;        if(st<=lft&&rht<=ed) return tree[ind].cnt;        else        {            PushDown(ind);            int mid=tree[ind].mid();            int cnt1=0,cnt2=0;            if(st<=mid) cnt1=query(st,ed,LL(ind));            if(ed> mid) cnt2=query(st,ed,RR(ind));            PushUp(ind);            return cnt1+cnt2;        }    }    int findPos(int st,int ed,int valu,int ind)    {        int lft=tree[ind].lft,rht=tree[ind].rht;        if(lft==rht) return lft;        else        {            PushDown(ind);            int mid=tree[ind].mid(),pos;            if(ed<=mid) pos=findPos(st,ed,valu,LL(ind));            else if(st>mid) pos=findPos(st,ed,valu,RR(ind));            else            {                if(tree[LL(ind)].cnt>=valu) pos=findPos(st,ed,valu,LL(ind));                else pos=findPos(st,ed,valu-tree[LL(ind)].cnt,RR(ind));            }            PushUp(ind);            return pos;        }    }}seg;int main(){    //freopen("04.in","r",stdin);    int t;    scanf("%d",&t);    while(t--)    {        int n,m; scanf("%d%d",&n,&m);        seg.build(0,n-1,1);        for(int i=0;i<m;i++)        {            int a,b,c; scanf("%d%d%d",&a,&b,&c);            if(a==1)            {                int tmp=seg.query(b,n-1,1);                b=min(b,n-1);                if(tmp==0)                {                    puts("Can not put any one.");                    continue;                }                else if(tmp<=c) c=tmp;                int sum=0;                if(b-1>=0) sum=seg.query(0,b-1,1);                int pos1=seg.findPos(0,n-1,sum+1,1);                int pos2=seg.findPos(0,n-1,c+sum,1);                seg.updata(pos1,pos2,1,1);                printf("%d %d\n",pos1,pos2);            }            else            {                b=min(b,n-1); c=min(c,n-1);                int sum=seg.query(b,c,1);                seg.updata(b,c,-1,1);                printf("%d\n",c-b+1-sum);            }        }        puts("");    }    return 0;}