线段树

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

原文地址:https://www.cnblogs.com/nowornever/p/4101916.html