pku1823 Hotel

线段树+模拟

空房间标记为1,已入住房间标记为0,这种表示便于统计某段区间内的连续空段长度

 

 

#include  < iostream >
#include 
< algorithm >
using   namespace  std;

#define  MAXN 160010
#define  Max(a,b) (a>b?a:b)

int  n,p;

struct  Node{
    
int  l,r,
    mx,
// 最大空段长度
    lmx, // 从区间左端开始的空段的最大长度
    rmx; //

    
bool  flag1, // true表示该段全为1(即该段全为空)
    flag0; // true表示该段全为0(该段无空位)
}nod[ 3 * MAXN];


void  build( int  u, int  l, int  r){
    nod[u].flag1
= true ;
    nod[u].flag0
= false ;
    nod[u].l
= l;
    nod[u].r
= r;
    nod[u].lmx
= nod[u].rmx = nod[u].mx = r - l + 1 ;
    
if (l == r)
        
return ;
    build(
2 * u,l,(l + r) / 2 );
    build(
2 * u + 1 ,(l + r) / 2 + 1 ,r);
}

void  checkin( int  u, int  l, int  r){
    
//  将父亲信息继承给左右儿子 // *
     if (nod[u].flag1){
        nod[u].flag1
= false ;

        nod[
2 * u].flag1 = true ;
        nod[
2 * u].flag0 = false ;
        nod[
2 * u].mx = nod[ 2 * u].lmx = nod[ 2 * u].rmx = nod[ 2 * u].r - nod[ 2 * u].l + 1 ;
        

        nod[
2 * u + 1 ].flag1 = true ;
        nod[
2 * u + 1 ].flag0 = false ;
        nod[
2 * u + 1 ].mx = nod[ 2 * u + 1 ].lmx = nod[ 2 * u + 1 ].rmx = nod[ 2 * u + 1 ].r - nod[ 2 * u + 1 ].l + 1 ;
        
    }
    
    
if (l <= nod[u].l  &&  nod[u].r <= r){    
        nod[u].lmx
= nod[u].rmx = nod[u].mx = 0 ;
        nod[u].flag0
= true ;
        
return ;
    }
    
if (l <= nod[ 2 * u].r)
        checkin(
2 * u,l,r);
    
if (nod[ 2 * u + 1 ].l <= r)
        checkin(
2 * u + 1 ,l,r);

    
//  由左右儿子更新维护父亲 // *
    nod[u].mx = Max(nod[ 2 * u].mx,nod[ 2 * u + 1 ].mx);
    nod[u].mx
= Max(nod[u].mx,nod[ 2 * u].rmx + nod[ 2 * u + 1 ].lmx);

    
if (nod[ 2 * u].lmx == nod[ 2 * u].r - nod[ 2 * u].l + 1 )
        nod[u].lmx
= nod[ 2 * u].lmx + nod[ 2 * u + 1 ].lmx;
    
else
        nod[u].lmx
= nod[ 2 * u].lmx;


    
if (nod[ 2 * u + 1 ].rmx == nod[ 2 * u + 1 ].r - nod[ 2 * u + 1 ].l + 1 )
        nod[u].rmx
= nod[ 2 * u + 1 ].rmx + nod[ 2 * u].rmx;
    
else
        nod[u].rmx
= nod[ 2 * u + 1 ].rmx;

    
if (nod[u].mx == 0 )
        nod[u].flag0
= true ;
}

void  checkout( int  u, int  l, int  r){
    
if (nod[u].flag0){
        nod[u].flag0
= false ;

        nod[
2 * u].flag0 = true ;
        nod[
2 * u].flag1 = false ;
        nod[
2 * u].mx = nod[ 2 * u].lmx = nod[ 2 * u].rmx = 0 ;
        
    
        nod[
2 * u + 1 ].flag0 = true ;
        nod[
2 * u + 1 ].flag1 = false ;
        nod[
2 * u + 1 ].mx = nod[ 2 * u + 1 ].lmx = nod[ 2 * u + 1 ].rmx = 0 ;
        
    }

    
if (l <= nod[u].l  &&  nod[u].r <= r){    
        nod[u].lmx
= nod[u].rmx = nod[u].mx = nod[u].r - nod[u].l + 1 ;
        nod[u].flag1
= true ;
        
return ;
    }
    
if (l <= nod[ 2 * u].r)
        checkout(
2 * u,l,r);
    
if (nod[ 2 * u + 1 ].l <= r)
        checkout(
2 * u + 1 ,l,r);

    nod[u].mx
= Max(nod[ 2 * u].mx,nod[ 2 * u + 1 ].mx);
    nod[u].mx
= Max(nod[u].mx,nod[ 2 * u].rmx + nod[ 2 * u + 1 ].lmx);

    
if (nod[ 2 * u].lmx == nod[ 2 * u].r - nod[ 2 * u].l + 1 )
        nod[u].lmx
= nod[ 2 * u].lmx + nod[ 2 * u + 1 ].lmx;
    
else
        nod[u].lmx
= nod[ 2 * u].lmx;


    
if (nod[ 2 * u + 1 ].rmx == nod[ 2 * u + 1 ].r - nod[ 2 * u + 1 ].l + 1 )
        nod[u].rmx
= nod[ 2 * u + 1 ].rmx + nod[ 2 * u].rmx;
    
else
        nod[u].rmx
= nod[ 2 * u + 1 ].rmx;


    
if (nod[u].mx == nod[u].r - nod[u].l + 1 )
        nod[u].flag1
= true ;
}

int  main(){
    
int  c,l,r;
    
while (scanf( " %d%d " , & n, & p) != EOF){
        build(
1 , 1 ,n);
        
while (p -- ){
            scanf(
" %d " , & c);
            
if (c == 1 ){
                scanf(
" %d%d " , & l, & r);
                checkin(
1 ,l,l + r - 1 );
            }
            
else   if (c == 2 ){
                scanf(
" %d%d " , & l, & r);
                checkout(
1 ,l,l + r - 1 );
            }
            
else
                printf(
" %d\n " ,nod[ 1 ].mx);
        }
    }
    
return   0 ;
}

    

你可能感兴趣的:(pku)