POJ 3667 Hotel 线段树 区间合并

来源:互联网 发布:php无限极分类菜单 编辑:程序博客网 时间:2024/04/29 00:03

第一道这样的题目,转自这里点击打开链接

只是照抄了一下,然后体味了一下大神的思维,以及自己的不慎

#include<cstdio>#include<iostream>#include<cstring>#define left l,m,x<<1#define right m+1,r,x<<1|1#define LMT 50005using namespace std;//一般都是左子树多一点int msum[LMT<<2],rsum[LMT<<2],lsum[LMT<<2],cover[LMT<<2];//msum指的是在某个区间“内”的最大空白int max(int a,int b){    return a>b?a:b;}void build(int l,int r,int x){    msum[x]=lsum[x]=rsum[x]=r-l+1;    if(l==r)return;    int m=(l+r)>>1;    build(left);build(right);}void cut(int x,int have){    if(cover[x]!=-1)    {        cover[x<<1]=cover[x<<1|1]=cover[x];        msum[x<<1]=lsum[x<<1]=rsum[x<<1]=cover[x]?0:have-(have>>1);        msum[x<<1|1]=lsum[x<<1|1]=rsum[x<<1|1]=cover[x]?0:have>>1;        cover[x]=-1;    }}/***这个函数是子树重新覆盖后,记录对父节点的影响的***/void refill(int x,int have){    lsum[x]=lsum[x<<1];    rsum[x]=rsum[x<<1|1];    if(lsum[x]==have-(have>>1))lsum[x]+=lsum[x<<1|1];    if(rsum[x]==have>>1)rsum[x]+=rsum[x<<1];//别搞错了..    msum[x]=max(rsum[x<<1]+lsum[x<<1|1],max(msum[x<<1],msum[x<<1|1]));}void update(int L,int R,int c,int l,int r,int x){    if(L<=l&&r<=R)    {        msum[x]=rsum[x]=lsum[x]=c?0:r-l+1;        cover[x]=c;        return;    }    cut(x,r-l+1);    int m=(l+r)>>1;    if(L<=m)update(L,R,c,left);    if(R>m)update(L,R,c,right);    refill(x,r-l+1);}int query(int need,int l,int r,int x){    if(l==r)return l;    cut(x,r-l+1);    int m=(l+r)>>1;    if(msum[x<<1]>=need)return query(need,left);    if(rsum[x<<1]+lsum[x<<1|1]>=need)return m-rsum[x<<1]+1;    return query(need,right);}int main(){    int n,m;    scanf("%d%d",&n,&m);    build(1,n,1);    memset(cover,-1,sizeof cover);    while(m--)    {        int op,a,b,ans;        scanf("%d",&op);        if(op==1)        {            scanf("%d",&a);            if(msum[1]<a)printf("0\n");            else            {                ans=query(a,1,n,1);                printf("%d\n",ans);                update(ans,ans+a-1,1,1,n,1);            }        }        else        {            scanf("%d%d",&a,&b);            update(a,a+b-1,0,1,n,1);        }    }    return 0;}


原创粉丝点击