HDU 4614 Vases and Flowers

来源:互联网 发布:adblock plus mac 编辑:程序博客网 时间:2024/05/31 06:24

HDU 4614 Vases and Flowers

线段树

题意

两个数n,m, n表示花瓶数量0~n-1,开始全为空。接下来有m组,每组有数k,a,b;当k=1时, 从a位置开始插花,b为花数量,当花瓶有花时,跳过当前,直到找到空花瓶再插入,输出插入第一支花的位置和最后一支花的位置,花可以没插完,当一支都没有插入则输出Can not put any one.;当k=2时,清空【a,b】的花瓶,并输出在被清空的花的数量。

思路

线段树用1表示空位,0表示有花。
清空实质就是统计a,b之间有多少花,并把区间a,b强制置1。
插花要有点技巧,设置两个查询函数:查询l,r之间空位的数量,查询从第开头数p个空位到哪。
这样从a开始插b朵花:先查询a到末尾与多少空位x,若x==0输出没法插花;x小于b就把b换成x,实际插x朵;否则插b朵。然后查询开头到a有多少空位k,从开头数k+1个空位到哪,数k+b个空位到哪。这两个数就是实际插花的左右端点。在将这个区间全置0即可。

应该有线段树上二分的写法,可以直接查询从a往右数b个空瓶到哪,可是我不会写。

代码

注意题目从0开始编号,注意转换与边界处理。

#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<set>#include<iostream>#include<vector>#include<queue>#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define M(a,b) memset(a,b,sizeof(a))using namespace std;const int MAXN=50005;const int oo=0x3f3f3f3f;typedef long long LL;struct Stree{    int sum, lpos, rpos;    int set;    Stree() { sum=lpos=rpos=0;set=-1; }    Stree(int _a, int _b, int _c) { sum=_a, lpos=_b, rpos=_c; }}stree[MAXN<<2];void pushup(int rt){    stree[rt].sum=stree[rt<<1].sum+stree[rt<<1|1].sum;    stree[rt].lpos=(stree[rt<<1].lpos==-1 ? stree[rt<<1|1].lpos : stree[rt<<1].lpos);    stree[rt].rpos=(stree[rt<<1|1].rpos==-1 ? stree[rt<<1].rpos : stree[rt<<1|1].rpos);}void build(int l, int r, int rt){    stree[rt].lpos=stree[rt].rpos=stree[rt].set=-1;    stree[rt].sum=0;    if(l==r)    {        stree[rt].lpos=stree[rt].rpos=l;        stree[rt].sum=1;        return;    }    int mid=(l+r)>>1;    build(lson), build(rson);    pushup(rt);}void pushdown(int l, int r, int rt){    if(stree[rt].set!=-1)    {        int c=stree[rt].set;        stree[rt<<1].set=stree[rt<<1|1].set=c;stree[rt].set=-1;        int mid=(l+r)>>1;        if(c==0)        {            stree[rt<<1].lpos=stree[rt<<1].rpos=stree[rt<<1|1].lpos=stree[rt<<1|1].rpos=-1;            stree[rt<<1].sum=stree[rt<<1|1].sum=0;        }        else        {            stree[rt<<1].lpos=l;            stree[rt<<1].rpos=mid;            stree[rt<<1|1].lpos=mid+1;            stree[rt<<1|1].rpos=r;            stree[rt<<1].sum=mid-l+1;            stree[rt<<1|1].sum=r-mid;        }    }}int update(int L, int R, int col, int l, int r, int rt){    if(L<=l&&r<=R)    {        if(col==1)        {            int c=stree[rt].sum;            c=r-l+1-c;            stree[rt].sum=r-l+1;            stree[rt].set=1;            stree[rt].lpos=l, stree[rt].rpos=r;            return c;        }        else        {            int c=stree[rt].sum;            stree[rt].sum=0;            stree[rt].set=0;            stree[rt].lpos=-1, stree[rt].rpos=-1;            return c;        }    }    int mid=(l+r)>>1;    pushdown(l, r, rt);    int res=0;    if(mid<L) res=update(L, R, col, rson);    else if(R<=mid) res=update(L, R, col, lson);    else res=update(L, R, col, lson)+update(L, R, col, rson);    pushup(rt);    return res;}int query(int L, int R, int l, int r, int rt){    if(L<=l&&r<=R) return stree[rt].sum;    pushdown(l, r, rt);    int mid=(l+r)>>1;    if(R<=mid) return query(L, R, lson);    else if(mid<L) return query(L, R, rson);    else return query(L, R, lson)+query(L, R, rson);}int query_pos(int p, int l, int r, int rt){    if(l==r) return l;    else if(stree[rt].sum==p) return stree[rt].rpos;    int mid=(l+r)>>1;    pushdown(l, r, rt);    if(stree[rt<<1].sum>=p)        return query_pos(p, lson);    else         return query_pos(p-stree[rt<<1].sum, rson);}int main(){    int T;scanf("%d", &T);    while(T--)    {        int n, m;scanf("%d%d", &n, &m);        build(1, n, 1);        while(m--)        {            int a, b, c;scanf("%d%d%d", &a, &b, &c);            if(a==1)            {                b++;                int sum=query(b, n, 1, n, 1);                if(sum==0) puts("Can not put any one.");                else                {                    int pre=(b==1?0:query(1, b-1, 1, n, 1));                    c=min(c, sum);                    int l=query_pos(pre+1, 1, n, 1);                    int r=query_pos(pre+c, 1, n, 1);                    update(l, r, 0, 1, n, 1);                    printf("%d %d\n", l-1, r-1);                }            }            else            {                printf("%d\n", update(b+1, c+1, 1, 1, n, 1));            }        }        printf("\n");    }    //system("pause");    return 0;}
原创粉丝点击