POJ3667 Hotel Segment Tree

Title: There are many rooms in a hotel. We need to arrange accommodation for our guests. The following requirements are required:
1. The arrangement of rooms is linear (i.e. a line).
2. Each room can only be occupied by one person.
3. Each group accommodation can only be arranged in a continuous number, and if there are many conditions to meet, the starting position must be as early as possible.
4. If you can't live in the current team, output 0, otherwise output the starting number.
Thought: There is no way to get this topic, but fortunately it's a template question, so I set it with the template of learning long hair.
1. First of all, we need to maintain three variables, lmax, Rmax and mmax, which represent the maximum number of free positions from the left, right and middle parts of the current interval, respectively. In order to facilitate the statistics of the remaining number, we initialize the room condition to 1 to represent an empty house.
Secondly, update information (i.e. guest check-in). Because of the interval modification and the small amount of data, we need lazy tags to delay the update to reduce the time complexity.
3. The function of the last query function is to query the starting point of the earliest satisfying condition. Since it's the earliest, we need to start from the left to find the right one, so it's the left, middle and right search method.
In addition, it can be noted from the code that only when searching the middle subtree is the definite value returned, otherwise it is the return call of a function. It's interesting here, and it's also the key code. You can think about it carefully, as follows:

		if(t[k<<1].mmax>=len) 
			return query(k<<1,len);//Notice here. Find out the relationship! If the left and right boundaries have to be added or not used 
        else if(t[k<<1].rmax+t[k<<1|1].lmax>=len) 
        	return (t[k<<1|1].l-t[k<<1].rmax);
        else if(t[k<<1|1].mmax>=len) return 
        	query(k<<1|1,len);
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#define ll long long
#define cl(a,b) memset(a,b,sizeof(a))
#define maxn 50004
using namespace std;
int n,m;
struct node{
    int l,r,lmax,rmax,mmax,lazy;//Left Begins Longest Right Begins Longest Middle Block Longest
}t[maxn<<2];
void pushup(int k){
    t[k].lmax=t[k<<1].lmax;
    t[k].rmax=t[k<<1|1].rmax;
    if(t[k<<1].lmax==(t[k<<1].r-t[k<<1].l+1)){//If the left side is full
        t[k].lmax+=t[k<<1|1].lmax;
    }
    if(t[k<<1|1].rmax==(t[k<<1|1].r-t[k<<1|1].l+1)){
        t[k].rmax+=t[k<<1].rmax;
    }
    t[k].mmax=max(max(t[k<<1].mmax,t[k<<1|1].mmax),t[k<<1].rmax+t[k<<1|1].lmax);
    return;
}
void build(int k,int l,int r){
    t[k].l=l,t[k].r=r,t[k].lazy=-1;//lazy assignment-1
    t[k].lmax=t[k].rmax=t[k].mmax=(r-l+1);
    if(l==r){
        return;
    }else{
        int mid=(l+r)>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
        //pushup(k); // Write a normal script
    }
    return;
}
void pushdown(int k){
    if(t[k].lazy!=-1){
        t[k<<1].mmax=t[k<<1].lmax=t[k<<1].rmax=t[k].lazy*(t[k<<1].r-t[k<<1].l+1);
        t[k<<1|1].mmax=t[k<<1|1].lmax=t[k<<1|1].rmax=t[k].lazy*(t[k<<1|1].r-t[k<<1|1].l+1);
        t[k<<1].lazy=t[k<<1|1].lazy=t[k].lazy;
        t[k].lazy=-1;
    }
}
void updata(int k,int l,int r,int v){//l to r becomes v
    if(l<=t[k].l&&t[k].r<=r){//Not updated here!!! 
        t[k].mmax=t[k].lmax=t[k].rmax=v*(t[k].r-t[k].l+1);
        t[k].lazy=v;
    }else{
        pushdown(k);
        int mid=(t[k].l+t[k].r)>>1;
        if(l<=mid) updata(k<<1,l,r,v);
        if(mid<r) updata(k<<1|1,l,r,v);
        pushup(k);
    }
    return;
}
int query(int k,int len){//Minimum coordinates satisfying enough length for query
    if(t[k].l==t[k].r){
        return t[k].l;//Here we're going to return coordinates instead of values! zz 
    }else{
        pushdown(k);
        //Notice the following: first query whether the left subtree meets the criteria, then query the middle tree, and then query the right subtree. 
        if(t[k<<1].mmax>=len) return query(k<<1,len);//Notice here. Find out the relationship! If the left and right boundaries have to be added or not used 
        else if(t[k<<1].rmax+t[k<<1|1].lmax>=len) return (t[k<<1|1].l-t[k<<1].rmax);
        else if(t[k<<1|1].mmax>=len) return query(k<<1|1,len);
        return 0;//Here, return 0 is added to determine whether the current group will survive in all cases. 
    }
}
int main(){
    scanf("%d%d",&n,&m);
    build(1,1,n);
    while(m--){
        int op;
        scanf("%d",&op);
        if(op==1){//Check in
            int len;
            scanf("%d",&len);
            int sta=query(1,len);
            if(sta==0){//If you can't stay, persuade you to leave.
                printf("0\n");
            }else{//Make arrangements when you stay.
                printf("%d\n",sta);
                updata(1,sta,sta+len-1,0);
            }
        }else{//Move out
            int sta,len;
            scanf("%d%d",&sta,&len);
            updata(1,sta,sta+len-1,1);
        }
    }
    return 0;
}
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 Di (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

Posted by cr-ispinternet on Thu, 22 Aug 2019 06:58:36 -0700