• P2894 [USACO08FEB]酒店Hotel


    参考样例,第一行输入n,m ,n代表有n个房间,编号为1---n,开始都为空房,m表示以下有m行操作,以下 每行先输入一个数 i ,表示一种操作:

    若i为1,表示查询房间,再输入一个数x,表示在1--n 房间中找到长度为x的连续空房,输出连续x个房间中左端的房间号,尽量让这个房间号最小,若找不到长度为x的连续空房,输出0。

    若i为2,表示退房,再输入两个数 x,y 代表 房间号 x---x+y-1 退房,即让房间为空。

    非常好的一道线段树题   

    维护sum表示区间最大的连续空房间长度  le ri分表表示区间两边的连续长度 (用来维护sum用的) len 表示区间长度  更加方便 

    每次询问的时候先看看总的区间存不存在答案 sum【1】!!!

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    #define lson l,m,pos<<1
    #define rson m+1,r,pos<<1|1
    const int N=50000+5;
    int sum[N<<2],col[N<<2],le[N<<2],ri[N<<2],len[N<<2];
    
    
    void up(int pos)
    {
        if(sum[pos<<1]==len[pos<<1])
        le[pos]=len[pos<<1]+le[pos<<1|1];
        else
        le[pos]=le[pos<<1];
    
        if(sum[pos<<1|1]==len[pos<<1|1])
        ri[pos]=len[pos<<1|1]+ri[pos<<1];
        else
        ri[pos]=ri[pos<<1|1];
    
        sum[pos]=max( ri[pos<<1]+le[pos<<1|1],max( sum[pos<<1],sum[pos<<1|1]   ) );
    }
    //1 open 2 close
    void down(int pos)
    {
        if(col[pos])
        {
            col[pos<<1]=col[pos<<1|1]=col[pos];
            if(col[pos]==1)
            {
                sum[pos<<1]=le[pos<<1]=ri[pos<<1]=0;
                sum[pos<<1|1]=le[pos<<1|1]=ri[pos<<1|1]=0;
            }
            else
            {
                sum[pos<<1]=le[pos<<1]=ri[pos<<1]=len[pos<<1];
                sum[pos<<1|1]=le[pos<<1|1]=ri[pos<<1|1]=len[pos<<1|1];
            }
            col[pos]=0;
        }
    }
    
    void build(int l,int r,int pos)
    {
        col[pos]=0;
        le[pos]=ri[pos]=sum[pos]=len[pos]=r-l+1;
        if(l==r)return;
        int m=(l+r)>>1;
        build(lson);
        build(rson);
    }
    
    void add(int L,int R,int flag,int l,int r,int pos)
    {
        if(L<=l&&r<=R)
        {
            col[pos]=flag;
            if(flag==1)
                sum[pos]=le[pos]=ri[pos]=0;
            else sum[pos]=le[pos]=ri[pos]=len[pos];
            return ;
        }
        down(pos);
        int m=(l+r)>>1;
        if(L<=m)add(L,R,flag,lson);
        if(R>m)add(L,R,flag,rson);
        up(pos);
    }
    int query(int d,int l,int r,int pos)
    {
        if(l==r)return l;
        down(pos);
        int m=(l+r)>>1;
        if( sum[pos<<1]>=d )query(d,lson);
        else if( ri[pos<<1]+le[pos<<1|1]>=d )return m-ri[pos<<1]+1;
        else query(d,rson);
    }
    
    int main()
    {
        int n,m;
        RII(n,m);
        build(1,n,1);
        while(m--)
        {
            int x;RI(x);
            if(x==1)
            {
                int d;RI(d);
                if(sum[1]>=d)
                {
                    int L=query(d,1,n,1);
                    printf("%d
    ",L);
                    add(L,L+d-1,1, 1,n,1);
                }
                else printf("0
    ");
            }
            else
            {
                int a,b;RII(a,b);
                add(a,a+b-1,2,1,n,1);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ZooKeeper 相关知识
    zookeeper 启动和停止脚本
    es 6.4.3 版本的es的处理方式
    SpringBoot启动使用elasticsearch启动异常:Received message from unsupported version:[2.0.0] minimal compatible
    windows下安装elasticsearch-6.4.3和elasticsearch-head插件
    二项式公式
    计算公式
    大规模数据如何检索?
    设计数据服务:为报表服务提供服务接口
    win10 桌面快捷键技术
  • 原文地址:https://www.cnblogs.com/bxd123/p/10843842.html
Copyright © 2020-2023  润新知