zoukankan      html  css  js  c++  java
  • Hotel POJ

    Hotel  POJ - 3667 

    The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a vacation on the sunny shores of Lake Superior. Bessie, ever the competent travel agent, has named the Bullmoose Hotel on famed Cumberland Street as their vacation residence. This immense hotel has N (1 ≤ N ≤ 50,000) rooms all located on the same side of an extremely long hallway (all the better to see the lake, of course).

    The cows and other visitors arrive in groups of size Di (1 ≤ Di ≤ N) and approach the front desk to check in. Each group i requests a set of Di contiguous rooms from Canmuu, the moose staffing the counter. He assigns them some set of consecutive room numbers r..r+Di-1 if they are available or, if no contiguous set of rooms is available, politely suggests alternate lodging. Canmuu always chooses the value of r to be the smallest possible.

    Visitors also depart the hotel from groups of contiguous rooms. Checkout i has the parameters Xi and Di which specify the vacating of rooms Xi ..Xi +Di-1 (1 ≤ Xi ≤ N-Di+1). Some (or all) of those rooms might be empty before the checkout.

    Your job is to assist Canmuu by processing M (1 ≤ M < 50,000) checkin/checkout requests. The hotel is initially unoccupied.

    Input

    * Line 1: Two space-separated integers: N and M
    * Lines 2..M+1: Line i+1 contains request expressed as one of two possible formats: (a) Two space separated integers representing a check-in request: 1 and D(b) Three space-separated integers representing a check-out: 2, Xi, and Di

    Output

    * Lines 1.....: For each check-in request, output a single line with a single integer r, the first room in the contiguous sequence of rooms to be occupied. If the request cannot be satisfied, output 0.

    Sample Input

    10 6
    1 3
    1 3
    1 3
    1 3
    2 5 5
    1 6
    

    Sample Output

    1
    4
    7
    0
    5
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <map>
    #include <set>
    #include <list>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    #include <iomanip>
    #define ull unsigned long long
    #define ll long long
    #define pb push_back
    #define mem(sum,x) memset(sum,x,sizeof(sum))
    #define rep(i,start,end) for(int i=start;i<=end;i++)
    #define per(i,end,start) for(int i=end;i>=start;i--)
    #define tle ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    using namespace std;
    const int mod = 998244353;
    const int mxn = 2e5 +7;
    int _,n,m,t,k,u,v,ans,cnt,ok,lim,op;
    ll w[mxn] , cost[mxn] ,  far[mxn] , siz[mxn];
    char ch;
    #define lc now<<1
    #define rc now<<1|1
    string str ;
    struct node {ll l,r,val,lazy,mx,mn;}p[mxn<<4];
    int lmx[mxn] , rmx[mxn] , num[mxn] ,lazy[mxn] ;/// 区间左端点起最长连续区间,区间右端点起最长连续区间,整个节点区间最长连续区间,lazy标记
    void pushup(int l,int r,int now)
    {
        lmx[now] = lmx[lc] ; rmx[now] = rmx[rc];   /// 继承区间左端点起的最长连续区间,区间右端点起的最长连续区间
        int mid = (l+r)>>1;
        if(lmx[now]==mid-l+1) lmx[now]+=lmx[rc];   /// 区间左端点继承的最长连续区间等于区间长度,那么就加上右孩子的左端点起的最长连续区间
        if(rmx[now]==r-mid)   rmx[now]+=rmx[lc];   /// 区间右端点继承的最长连续区间等于区间长度,那么就加上左孩子的右端点起的最长连续区间
        num[now] = max( rmx[lc]+lmx[rc] , max(num[lc],num[rc]) );  /// 更新整个区间的最长连续区间值
    }
    void pushdown(int l,int r,int now)
    {
        if(lazy[now]>=0){  /// 标记为1 0 ,那么只要判断大于0即可
            int mid = (l+r)>>1;
            lazy[lc] = lazy[rc] = lazy[now] ;
            lmx[lc] = rmx[lc] = num[lc] = lazy[now]?0:(mid-l+1);
            lmx[rc] = rmx[rc] = num[rc] = lazy[now]?0:r-mid;
            lazy[now] = -1 ;
        }
    }
    void build(int l,int r,int now)
    {
        if(l==r){
            lmx[now] = rmx[now] = num[now] = 1 ; return ;  /// 初始化叶子节点的最长区间为1
        }
        int mid = (l+r)>>1;
        build(l,mid,lc);build(mid+1,r,rc);pushup(l,r,now); /// 向上更新最长区间值
    }
    void up(int l,int r,int L,int R,int now,int lim)  /// 整个区间的左右端点,更新区间的左右端点,树的节点,退房标记还是入住标记
    {
        if(L<=l && R>=r){
            num[now] = lmx[now] = rmx[now] = lim?0:(r-l+1);
            lazy[now] = lim ; /// 更新区间标记
            return ;
        }
        pushdown(l,r,now);
        int mid = (l+r)>>1;
        if(L<=mid) up(l,mid,L,R,lc,lim);
        if(R>mid)  up(mid+1,r,L,R,rc,lim);
        pushup(l,r,now);
    }
    int ask(int l,int r,int k,int now)
    {
        if(l==r) return l; /// 区间端点相同即叶子节点,直接返回区间端点
        pushdown(l,r,now); /// 向下传递lazy值
        int mid = (l+r)>>1 ;
        if(num[lc]>=k) return ask(l,mid,k,lc); /// 左区间最左连续区间满足需求的K个房间,则计算左区间
        if(rmx[lc]+lmx[rc]>=k) return mid-rmx[lc]+1; /// 左区间的最右连续区间和右区间的最左连续区间满足K个需求,则 均值 - 右区间的最左连续区间 + 1 即为左区间最右连续区间的起始值
        return ask(mid+1,r,k,rc); /// 在右区间查找
    }
    int main()
    {
        while(cin>>n>>m)
        {
            build(1,n,1);
            while(m--)
            {
                cin>>op;
                if(op==1){
                    cin>>k;
                    if(num[1]<k){ /// 特判整个区间是否满足K个房间的需求
                        cout<<0<<endl;continue;
                    }
                    ans = ask(1,n,k,1);
                    cout<<ans<<endl;
                    up(1,n,ans,ans+k-1,1,1); /// 将找到的连续K个房间标记为使用
                }else{
                    cin>>k>>cnt;
                    up(1,n,k,k+cnt-1,1,0);
                }
            }
        }
    }
    所遇皆星河
  • 相关阅读:
    php随笔3-thinkphp 学习-ThinkPHP3.1快速入门(1)基础
    自己动手写PHP MVC框架
    Aptana Studio 3 官方汉化包汉化
    PHP使用手册
    关系型数据库:关系模式设计原则
    Git使用教程
    高并发与负载均衡-nginx-session一致性
    高并发与负载均衡-nginx-安装-配置-location-负载均衡
    高并发与负载均衡-nginx-反向代理概念
    Java-笔记2
  • 原文地址:https://www.cnblogs.com/Shallow-dream/p/12829580.html
Copyright © 2011-2022 走看看