• 线段树


    Online JudgeProblem SetAuthorsOnline ContestsUser
    Web Board
    Home Page
    F.A.Qs
    Statistical Charts
    Problems
    Submit Problem
    Online Status
    Prob.ID:
    Register
    Update your info
    Authors ranklist
    Current Contest
    Past Contests
    Scheduled Contests
    Award Contest
    User ID:
    Password:
      Register
    Language:
    Hotel
    Time Limit: 3000MS   Memory Limit: 65536K
    Total Submissions: 12496   Accepted: 5378

    Description

    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
    

    Source

    [Submit]   [Go Back]   [Status]   [Discuss]

    Home Page   Go Back  To top

    //建树: 按照二叉树

    //结点信息:

       lsum:保存的是以L为起点往右的最长连续空位

       rsum:保存的是以R为起点往左的最长连续空位

       sum:保存的是区间[L, R]中的最长连续空位

    //操作信息:

       0:本节点区间均为空房

       1:本节点区间均已入住

       -1:未进行任何操作

    #include <cstdio>
    #include <iostream>
    
    using namespace std;
    
    struct Node{
        int l, r, lsum, rsum, sum;
        int s;
    }nodes[500000];
    
    int max(int a, int b){
        return a>b?a:b;
    }
    
    int maxx(int a, int b, int c){
         int x1 = max(a, b);
         int x2 = max(b,c);
         return max(x1,x2);
    }
    
    void build(int o, int L, int R){
         nodes[o].l = L;
         nodes[o].r = R;
         int Len = R-L+1;
         nodes[o].lsum = nodes[o].rsum = nodes[o].sum = Len;
         nodes[o].s  = -1;
    
         if(L!=R){
            int M = (L+R)/2;
            build(2*o, L, M);
            build(2*o+1, M+1, R);
         }
    }
    
    void push_down(int o){
        int Lc = 2*o, Rc = 2*o+1;
        if(nodes[o].s >= 0){
            nodes[Lc].s = nodes[Rc].s = nodes[o].s;
            if(nodes[o].s){
                nodes[Lc].lsum = nodes[Lc].rsum = nodes[Lc].sum  = 0;
                nodes[Rc].lsum = nodes[Rc].rsum = nodes[Rc].sum  = 0;
            }
            else{
                nodes[Lc].lsum = nodes[Lc].rsum = nodes[Lc].sum  = nodes[Lc].r - nodes[Lc].l + 1;
                nodes[Rc].lsum = nodes[Rc].rsum = nodes[Rc].sum = nodes[Rc].r - nodes[Rc].l + 1;
            }
            nodes[o].s = -1;
        }
    }
    
    void push_up(int o){
         int Lc = 2*o, Rc = 2*o+1;
         int Len1 = nodes[Lc].r - nodes[Lc].l + 1;
         int Len2 = nodes[Rc].r - nodes[Rc].l + 1;
    
         if(nodes[Lc].lsum == Len1) nodes[o].lsum = Len1+nodes[Rc].lsum;
         else nodes[o].lsum = nodes[Lc].lsum;
    
         if(nodes[Rc].rsum == Len2) nodes[o].rsum = Len2 + nodes[Lc].rsum;
         else nodes[o].rsum = nodes[Rc].rsum;
    
         nodes[o].sum = maxx(nodes[Lc].sum, nodes[Rc].sum, (nodes[Lc].rsum + nodes[Rc].lsum));
    }
    
    void updata(int o, int y1, int y2, int cnt){
         int Lc = 2*o, Rc = 2*o+1;
         int L = nodes[o].l;
         int R = nodes[o].r;
         int Len = R-L+1;
         if(y1<=L && y2>=R){
            nodes[o].s = cnt;
            if(cnt)  nodes[o].lsum = nodes[o].rsum = nodes[o].sum = 0;
            else     nodes[o].lsum = nodes[o].rsum = nodes[o].sum = Len;
         }
         else{
            push_down(o);
            int M = (L + R)/2;
            if(y2<=M) updata(Lc,y1,y2,cnt);
            else if(y1>M) updata(Rc, y1, y2, cnt);
            else{
                updata(Lc, y1, M, cnt);
                updata(Rc, M+1, y2, cnt);
            }
            push_up(o);           //»ØËݸüÐÂo
         }
    }
    
    int Search(int o, int len){
        int Lc = 2*o, Rc = 2*o+1;
        int L = nodes[o].l;
        int R = nodes[o].r;
    
        push_down(o);
        if(nodes[o].sum < len) return 0;
        if(L == R) return L;
        if(nodes[Lc].sum >= len){
            return Search(Lc, len);
        }
        else if((nodes[Lc].rsum + nodes[Rc].lsum) >= len){
            int lef = (L+R)/2 - nodes[Lc].rsum + 1;
            int rig = lef + len - 1;
            return lef;
        }
        else return Search(Rc, len);
    }
    
    
    
    int main(){
        int N,M;
        scanf("%d%d",&N, &M);
        build(1,1,N);
        while(M--){
            int cas;
            scanf("%d",&cas);
            if(cas == 1){
                int len;
                scanf("%d",&len);
                int ans = Search(1,len);
                printf("%d
    ",ans);
                if(ans) updata(1,ans,ans+len-1,1);
            }
            else{
                int b,len;
                scanf("%d%d",&b,&len);
                updata(1,b,b+len-1,0);
            }
        }
        return 0;
    }

    All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
    Any problem, Please Contact Administrator

  • 相关阅读:
    Excel 函数
    selenium+python自动化测试(二)对浏览器的简单操作
    selenium+python自动化测试(一)环境
    py中mongodb使用
    ESQL调oracle存储过程
    boost.asio简单入坑
    浅析tcp中read阻塞
    14 天堂电影信息爬取
    13 爬取豆瓣电影网电影信息
    12 lxml&XPath结合使用(提取数据详解)
  • 原文地址:https://www.cnblogs.com/nowornever/p/4101916.html
Copyright © 2020-2023  润新知