线段树

 

题目意思大概就是有一连串的房子。客人来时会要求订其中连续的 k 个房子,要你给出连续 k 个房子的最小编号。同时也会退订房间的操作。

用线段树来维护房子的订阅情况。线段树记录 4 个域。

Cpp代码 
  1. struct Node{  
  2.     int Lx;     //  区间从左端点起连续的最大长度   
  3.     int Rx;     //  区间以右端点结束的最大连续长度   
  4.     int Ax;     //  区间全局最大连续长度   
  5.     int cover;  //  标记区间是否被覆盖 0, 1, -1   
  6. };  

cover 为 0 表示这个区间里的房子都没订,为 1 表示这个区间房子都订了, 为 -1 表示其它情况。

Lx,  Rx 是为了更新 Ax。。

 

代码:

Cpp代码 
  1. #include <iostream>  
  2. #include <algorithm>  
  3. #include <cstdio>  
  4. #include <cstdlib>  
  5. #include <cstring>  
  6. using namespace std;  
  7.   
  8. int const N= 50010;  
  9. int n, m;  
  10. int COLOR;  
  11.   
  12. struct Node{  
  13.     int Lx;     //  区间从左端点起连续的最大长度   
  14.     int Rx;     //  区间以右端点结束的最大连续长度   
  15.     int Ax;     //  区间全局最大连续长度   
  16.     int cover;  //  标记区间是否被覆盖 0, 1, -1   
  17. }  
  18.   
  19. tb[N<<2];  
  20.   
  21. void build( int L, int R, int rt ){  
  22.     if( L== R ){  
  23.         tb[rt].Lx= 1; tb[rt].Rx= 1; tb[rt].Ax= 1;  
  24.         return;  
  25.     }  
  26.       
  27.     int mid= (L+ R)>>1;  
  28.     build( L, mid, rt<<1 );  
  29.     build( mid+ 1, R, rt<<1|1 );  
  30.       
  31.     tb[rt].Lx= tb[rt].Rx= tb[rt].Ax= R- L+ 1;  
  32.     tb[rt].cover= 0;  
  33. }  
  34.   
  35. int query( int x, int L, int R, int rt ){  
  36.     if( tb[rt].Ax== x && R- L+ 1== x ) return L;  
  37.       
  38.     if( tb[rt].Ax>= x ){  
  39.         int mid= (L+ R)>>1;  
  40.           
  41.         if( tb[rt].cover!= -1 ){  
  42.             tb[rt<<1].cover= tb[rt<<1|1].cover= tb[rt].cover;  
  43.               
  44.             if( tb[rt].cover== 0 ){  
  45.                 tb[rt<<1].Ax= tb[rt<<1].Lx= tb[rt<<1].Rx= mid- L+ 1;  
  46.                 tb[rt<<1|1].Ax= tb[rt<<1|1].Lx= tb[rt<<1|1].Rx= R- mid;  
  47.             }  
  48.             else{  
  49.                 tb[rt<<1].Ax= tb[rt<<1].Lx= tb[rt<<1].Rx= 0;  
  50.                 tb[rt<<1|1].Ax= tb[rt<<1|1].Lx= tb[rt<<1|1].Rx= 0;  
  51.             }  
  52.             tb[rt].cover= -1;  
  53.         }  
  54.           
  55.         if( tb[rt<<1].Ax>= x ) return query( x, L, mid, rt<<1 );  
  56.         else if( min( mid- L+ 1, tb[rt<<1].Rx )+ min( R- mid, tb[rt<<1|1].Lx )>= x ){  
  57.             return mid- min(  mid- L+ 1, tb[rt<<1].Rx )+ 1;  
  58.         }  
  59.         else if( tb[rt<<1|1].Ax>= x ) return query( x, mid+ 1, R, rt<<1| 1 );  
  60.     }  
  61.       
  62.     return 0;  
  63. }  
  64.   
  65. void update( int x, int y, int L, int R, int rt ){  
  66.     if( L== x && R== y ){  
  67.         tb[rt].cover= COLOR;  
  68.         if( COLOR== 0 ) tb[rt].Ax= tb[rt].Lx= tb[rt].Rx= R- L+ 1;  
  69.         else tb[rt].Ax= tb[rt].Lx= tb[rt].Rx= 0;  
  70.         return;  
  71.     }  
  72.       
  73.     int mid= (L+ R)>>1;  
  74.     if( tb[rt].cover!= -1 ){  
  75.         tb[rt<<1].cover= tb[rt<<1|1].cover= tb[rt].cover;  
  76.           
  77.         if( tb[rt].cover== 0 ){  
  78.             tb[rt<<1].Ax= tb[rt<<1].Lx= tb[rt<<1].Rx= mid- L+ 1;  
  79.             tb[rt<<1|1].Ax= tb[rt<<1|1].Lx= tb[rt<<1|1].Rx= R- mid;  
  80.         }  
  81.         else{  
  82.             tb[rt<<1].Ax= tb[rt<<1].Lx= tb[rt<<1].Rx= 0;  
  83.             tb[rt<<1|1].Ax= tb[rt<<1|1].Lx= tb[rt<<1|1].Rx= 0;  
  84.         }  
  85.         tb[rt].cover= -1;  
  86.     }  
  87.       
  88.     if( y<= mid ) update( x, y, L, mid, rt<<1 );  
  89.     else if( x> mid ) update( x, y, mid+ 1, R, rt<<1|1 );  
  90.     else{  
  91.         update( x, mid, L, mid, rt<<1 );  
  92.         update( mid+ 1, y,  mid+ 1, R, rt<<1|1 );  
  93.     }  
  94.       
  95.     tb[rt].Ax= max( tb[rt<<1].Ax, tb[rt<<1|1].Ax );  
  96.     if( tb[rt<<1].Lx== mid- L+ 1 ) tb[rt].Lx= tb[rt<<1].Lx+ tb[rt<<1|1].Lx;  
  97.     else tb[rt].Lx= tb[rt<<1].Lx;  
  98.       
  99.     if( tb[rt<<1|1].Rx== R- mid ) tb[rt].Rx= tb[rt<<1|1].Rx+ tb[rt<<1].Rx;  
  100.     else tb[rt].Rx= tb[rt<<1|1].Rx;  
  101.       
  102.     tb[rt].Ax= max( tb[rt].Ax, max( tb[rt].Lx, tb[rt].Rx ) );  
  103.     tb[rt].Ax= max( tb[rt].Ax, tb[rt<<1].Rx+ tb[rt<<1|1].Lx );  
  104. }  
  105.   
  106. int main(){  
  107.     scanf("%d%d",&n,&m );  
  108.       
  109.     build( 1, n, 1 );  
  110.     forint i= 0; i< m; ++i ){  
  111.         int x, y, z;  
  112.         scanf("%d",&x);  
  113.           
  114.         if( x== 1 ){  
  115.             scanf("%d",&y );  
  116.               
  117.             int pos= query( y, 1, n, 1 );  
  118.             printf("%d/n", pos );  
  119.               
  120.             if( pos!= 0 ){  
  121.                 COLOR= 1;  
  122.                 update( pos, pos+ y- 1, 1, n, 1 );  
  123.             }  
  124.         }  
  125.         else{  
  126.             scanf("%d%d",&y,&z );  
  127.               
  128.             COLOR= 0;  
  129.             update( y, y+ z- 1, 1, n, 1 );  
  130.         }  
  131.     }  
  132.       
  133.     return 0;  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值