(Segment tree) (h) poj3667 (interval merger)

poj3667 Hotel

As part you do not understand when reading this article, please ask in the comments section, or jump tree line general introduction

 


[Title] effect

A hotel, a room with N in a row, there are two operations, first there is a customer to check X X consecutive rooms,
the required output of the left position of the minimum point, it can not satisfy the output 0, of Second, L will begin, a length X of a continuous empty room.

[Input file]

The first two row numbers N, M, represents the number of rooms and operand

Next M lines, each line there are two cases:

Operation 1 1 X is do

2 represents the operation LX 2

[Output file]

1 For each operation, the output of the answer.

 

Problem is the demand continuum leftmost and the juxtaposition of some full range blank.

Then our tree line has officially entered the zone of partial merger

 

0 means no cattle, live cattle represents 1

Represented by pre (precursor) the number of leading zeros within the interval, last (the successor, but it was better with suf wrote last not want to change, and a meaning), the guide indicates the number of zero, Maxilen represent the maximum continuous interval 0 number

, Tag represents the entire range of the Tag is set (the initial value is -1)

 

pushup special situation, if left / right interval predecessor / successor  completely cover the left / right  range, to special treatment

if(pre[LS]==mid-l+1)pre[rt]=pre[RS]+pre[LS];
else pre[rt]=pre[LS];
if(last[RS]==r-mid)last[rt]=last[RS]+last[LS];
else last[rt]=last[RS];
Maxilen [RT] = max (Maxilen [the LS], Maxilen [the RS], pre [the RS] Last + [the LS]); 
// Maximum possible continuum left / right / center (So why maintenance precursor successor)

 

pushdown

The whole operation, Fu Fu 0 or 1

 tag[LS]=tag[RS]=tag[rt];
 MaxiLen[LS]=pre[LS]=last[LS]=!tag[rt]?(mid-l+1):0;
 MaxiLen[RS]=pre[RS]=last[RS]=!tag[rt]?(r-mid):0;
 tag[rt]=-1; 

 

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
using namespace std;
const int N=2e6+3;
int pre[N<<2],last[N<<2],MaxiLen[N<<2],tag[N<<2];
int n,m,L;
//tag -1 -> Nothing 0 ; 0/1 -> get to 0/1 
#define LS (rt<<1)
#define RS (LS|1)
void pushup(int rt,int l,int r){
    MaxiLen[rt]=max(max(MaxiLen[LS],MaxiLen[RS]),pre[RS]+last[LS]);
    int mid=l+r>>1;
    if(pre[LS] == mid-l+1)pre[rt]=mid-l+1+pre[RS];
    else pre[rt]=pre[LS];
    if(last[RS] == r-mid)last[rt]=r-mid+last[LS];
    else last[rt]=last[RS];
}
void build(int rt,int l,int r){
    pre[rt]=last[rt]=MaxiLen[rt]=r-l+1;
    tag[rt]=-1;
    if(l==r)return;
    int mid=l+r>>1;
    build(LS,l,mid);
    build(RS,mid+1,r);
    //pushup(rt,l,r);
}
void pushdown(int rt,int l,int r){
    if(tag[rt] == -1)return;
    tag[LS]=tag[RS]=tag[rt];
    int mid=l+r>>1;
    MaxiLen[LS]=pre[LS]=last[LS]=!tag[rt]?(mid-l+1):0;
    MaxiLen[RS]=pre[RS]=last[RS]=!tag[rt]?(r-mid):0;
    tag[rt]=-1; return;
}
void update(int rt,int l,int r,int x,int y,int p){
    if(l>=x&&r<=y){
        tag[rt]=p; //直接覆盖
        MaxiLen[rt]=!p?(r-l+1):0;
        pre[rt]=last[rt]=!p?(r-l+1):0;
        return;
    }pushdown(rt,l,r);
    int MID = L + R & lt >> . 1 ;
     IF (X <= MID) Update (the LS, L, MID, X, Y, P);
     IF (Y> MID) Update (the RS, MID + . 1 , R & lt, X, Y , P); 
    a pushup (RT, L, R & lt); return ; 
} 
int Query ( int RT, int L, int R & lt, int LEN) {
     IF (R & lt == L) return L;   // a point, as has been preferentially to the left, so the leftmost point must be
     int MID = L + R & lt >> . 1 ; 
    pushdown (RT, L, R & lt); 
    IF (MaxiLen [the LS]> = LEN) return Query (the LS, L, MID, LEN);
     IF(last[LS]+pre[RS]>=LEN) return mid-last[LS]+1; //取得左儿子后继的开端
    if(MaxiLen[RS]>=LEN) return query(RS,mid+1,r,LEN);
    return 0; //if(MaxiLen[rt]<LEN)return 0;
}
int main(){
    scanf("%d%d",&n,&m);
        build(1,1,n);
        int ty,x,L;
        while(m--){
            scanf("%d",&ty);
            if(ty==1){
                scanf("%d",&x);
                L=query(1,1,n,x);
                printf("%d\n",L);
                if(L)update(1,1,n,L,L+x-1,1);
            }else {
                scanf("%d%d",&L,&x);
                update(1,1,n,L,L+x-1,0);
            }
        }
    
    return 0;
}

Color is not very good looking qwq

End

Guess you like

Origin www.cnblogs.com/lsy263/p/11229039.html