zoukankan      html  css  js  c++  java
  • poj 3667 Hotel 线段树

    题意:1 a:询问是不是有连续长度为a的空房间,有的话住进最左边
    2 a b:将[a,a+b-1]的房间清空

    #include <stdio.h>
    #define maxn 51000
    int sum[4*maxn],lsum[4*maxn],rsum[4*maxn];
    int vis[4*maxn];
    int max(int a,int b)
    {
        if(a>b) return a;
        else return b;
    }
    void pushup(int o,int l,int r)
    {
        int m=(l+r)/2;
        lsum[o]=lsum[o*2];
        rsum[o]=rsum[o*2+1];
        if(lsum[o]==m-l+1) lsum[o]+=lsum[o*2+1];
        if(rsum[o]==r-m) rsum[o]+=rsum[o*2];
        sum[o]=max(lsum[o*2+1]+rsum[o*2],max(sum[o*2],sum[o*2+1]));
    }
    void pushdown(int o,int l,int r)
    {
        if(vis[o]!=-1)
        {
            int m=r-l+1;
            vis[o*2]=vis[o*2+1]=vis[o];
            sum[o*2]=lsum[o*2]=rsum[o*2]=vis[o]?0:m-(m/2);
    		sum[o*2+1]=lsum[o*2+1]=rsum[o*2+1]=vis[o]?0:(m/2);
            vis[o]=-1;
        }
    }
    void build(int l,int r,int o)
    {
        sum[o]=lsum[o]=rsum[o]=r-l+1;
        vis[o]=-1;
        if(l==r) return ;
        else
        {
            int m=(l+r)/2;
            build(l,m,o*2);
            build(m+1,r,o*2+1);
        }
    }
    void update(int ql,int qr,int flag,int l,int r,int o)
    {
        if(ql<=l&&r<=qr)
        {
            vis[o]=flag;
            if(flag==0) sum[o]=lsum[o]=rsum[o]=r-l+1;
            else if(flag==1) sum[o]=lsum[o]=rsum[o]=0;
            return ;
        }
        else
        {
            pushdown(o,l,r);
            int m=(l+r)/2;
            if(ql<=m) update(ql,qr,flag,l,m,o*2);
            if(qr>m) update(ql,qr,flag,m+1,r,o*2+1);
            pushup(o,l,r);
        }
    }
    int query(int d,int l,int r,int o)
    {
        if(l==r) return l;
        else
        {
            pushdown(o,l,r);
            int m=(l+r)/2;
            if(sum[o*2]>=d) return query(d,l,m,o*2);
            else if(rsum[o*2]+lsum[o*2+1]>=d) return m-rsum[o*2]+1;
            else return query(d,m+1,r,o*2+1);
        }
    }
    int main()
    {
        int n,m;
        int i,y,x,d;
        scanf("%d%d",&n,&m);
        build(1,n,1);
        for(i=1;i<=m;i++)
        {
            scanf("%d",&y);
            if(y==2)    //out
            {
                scanf("%d%d",&x,&d);
                update(x,x+d-1,0,1,n,1);
            }
            else     //in
            {
                scanf("%d",&d);
                if(sum[1]<d) printf("0
    ");
                else
                {
                    int ans=query(d,1,n,1);
                    printf("%d
    ",ans);
                    update(ans,ans+d-1,1,1,n,1);
                }
            }
        }
        return 0;
    }
    


     


     

  • 相关阅读:
    日期和时间
    怎样将GB2312编码的字符串转换为ISO-8859-1编码的字符串?
    数据类型之间的转换:
    类的加载顺序,支出下列程序的输出结果
    内部类
    对象的类型转换
    简单继承
    封装
    计算a+b
    U盘删除文件时提示“文件或目录损坏且无法读取”的解决方法
  • 原文地址:https://www.cnblogs.com/vermouth/p/3710138.html
Copyright © 2011-2022 走看看