pojHotel 线段树

//空间分配
//1 x 找连续的长度为x的空间
//2  x d [x,x+d-1]空间的占用清除
//维护ma_l , ma_r , ma分别为左边的空闲空间,右边的空闲空间和最大的空闲空间
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
const int maxn = 50010 ;
#define left v<<1
#define right v<<1|1
struct node
{
    int l , r , lazy ;
    int ma_l , ma_r , ma ;
}tree[maxn<<2] ;
void build(int l , int  r , int v)
{
    tree[v].l = l ;
    tree[v].r = r;
    tree[v].lazy = -1 ;
    tree[v].ma = tree[v].ma_l = tree[v].ma_r = (r - l + 1) ;
    if(l == r)return ;
    int mid = (l + r) >> 1 ;
    build(l , mid , left) ;
    build(mid +  1 , r , right) ;
}
void push_down(int v)
{
    if(tree[v].lazy != -1)
    {
        tree[left].ma_l = tree[left].ma_r = tree[left].ma = (tree[left].r - tree[left].l + 1)*tree[v].lazy ;
        tree[right].ma_l = tree[right].ma_r = tree[right].ma = (tree[right].r - tree[right].l + 1)*tree[v].lazy ;
        tree[left].lazy = tree[right].lazy = tree[v].lazy ;
        tree[v].lazy = -1 ;
    }
}
void push_up(int v)
{
    tree[v].ma_l = tree[left].ma_l ;
    tree[v].ma_r = tree[right].ma_r ;
    tree[v].ma = max(max(tree[left].ma , tree[right].ma) , tree[left].ma_r + tree[right].ma_l);
    if(tree[v].ma_l == (tree[left].r - tree[left].l + 1))
    tree[v].ma_l += tree[right].ma_l;
    if(tree[v].ma_r == (tree[right].r - tree[right].l + 1))
    tree[v].ma_r += tree[left].ma_r ;
 }
 void update(int l , int r, int v , int op)
 {
     if(l <= tree[v].l && tree[v].r <= r)
     {
         tree[v].ma_l = tree[v].ma_r = tree[v].ma = (tree[v].r - tree[v].l + 1)*op ;
         tree[v].lazy = op ;
         return  ;
     }
     push_down(v) ;
     int mid = (tree[v].l + tree[v].r) >> 1 ;
     if(l <= mid)update(l , r , left , op) ;
     if(r > mid)update(l , r ,right , op) ;
     push_up(v) ;
 }
 int query(int v , int num)
 {
     if(tree[v].l == tree[v].r)
     return tree[v].l ;
     push_down(v) ;
     int mid = (tree[v].l + tree[v].r) >> 1 ;
     if(tree[left].ma >= num)
     return query(left , num) ;
     else if(tree[left].ma_r + tree[right].ma_l >= num)
     return tree[left].r - tree[left].ma_r + 1 ;
     else return query(right , num) ;
 }
 int main()
 {
     //freopen("in.txt" ,"r" , stdin) ;
     int  n , m ;
     while(~scanf("%d%d" , &n , &m))
     {
         build(1 , n , 1) ;
         while(m--)
         {
             int op , d , x ;
             scanf("%d" , &op) ;
             if(op == 1)
             {
                 scanf("%d" ,&x) ;
                 int ans = query(1 , x) ;
                 if(tree[1].ma < x){puts("0");continue ;}
                 printf("%d\n" ,ans) ;
                 update(ans , ans + x - 1 , 1 , 0) ;
             }
             else if(op == 2)
             {
                 scanf("%d%d" ,&x , &d) ;
                 update(x , x+d-1 , 1 , 1) ;
             }
         }
     }
     return  0 ;
 }











































































你可能感兴趣的:(pojHotel 线段树)