poj 3667 Hotel(線段樹 # 7)

維護一個左起連續空房間的長度ls,右起連續空房間的長度rs,以及一個最大連續空房間數sum。

注意更新子節點後,要更新父節點的cov即lazy值

1032 ms

#include <cstdio>
 #include <cstdlib>
 #include <algorithm> 
 #define L(t) t << 1
 #define R(t) t << 1 | 1 
 //#define /2  >> 1 
 //影響時間效率?
 using namespace std;
 #define N 50010 
 
 struct node{
        int cov;
        int l, r;
        int ls, rs, sum;
 }Tree[N * 4]; 
 //大小?
 
 void build(int l, int r, int x)
 {
        Tree[x].l = l;
        Tree[x].r = r;
        Tree[x].cov = 0;
        Tree[x].ls = Tree[x].rs = Tree[x].sum = r - l + 1;
        if (l == r)return;
        int mid = (l + r) /2;
        build(l, mid, L(x));
        build(mid + 1, r, R(x));
 }
 void update_sum(int x)
 {     
        if (Tree[x].cov == 0)
        {
                   Tree[x].sum = Tree[x].ls = Tree[x].rs = Tree[x].r - Tree[x].l + 1; 
        }
        else 
        {
                    Tree[x].sum = Tree[x].ls = Tree[x].rs = 0;
        }
 }
   
void update_cov(int x)
{     
        if (Tree[L(x)].cov == 0 && Tree[R(x)].cov == 0)
                  Tree[x].cov = 0;
        else if (Tree[L(x)].cov == 1 && Tree[R(x)].cov == 1)
                  Tree[x].cov = 1;
        else 
             Tree[x].cov = -1;
}
                    
                    
                    
 void update(int l, int r, int cov, int x)
 {
        if (Tree[x].cov == cov)return;
        if (Tree[x].l == l && Tree[x].r == r)
        {
                 Tree[x].cov = cov;
                 update_sum(x);
                 return;
        }
        if (Tree[x].l == Tree[x].r)return;
        if (Tree[x].cov != -1)
        {
                 Tree[L(x)].cov = Tree[R(x)].cov = Tree[x].cov;
                 update_sum(L(x));
                 update_sum(R(x));
        }
        int mid = (Tree[x].l + Tree[x].r) /2;
        if (l > mid)
             update(l, r, cov, R(x));
        else if (r <= mid)
             update(l, r, cov, L(x));
        else 
        {
               update(l, mid, cov, L(x));
               update(mid + 1, r, cov, R(x));
        }
        update_cov(x);
        Tree[x].ls = Tree[L(x)].ls + (Tree[L(x)].cov == 0?Tree[R(x)].ls : 0) ;
        Tree[x].rs = Tree[R(x)].rs + (Tree[R(x)].cov == 0? Tree[L(x)].rs: 0) ;
        Tree[x].sum = max(max(Tree[L(x)].sum, Tree[R(x)].sum), Tree[L(x)].rs + Tree[R(x)].ls);
 } 
         
 int find(int nu, int x)
 {
        if (Tree[x].cov == 0 && Tree[x].sum >= nu)
             return Tree[x].l;
        if (Tree[x].cov == 1)return 0;
        if (Tree[L(x)].sum >= nu)
             return find(nu, L(x));
        if (Tree[L(x)].rs + Tree[R(x)].ls >= nu)
             return (Tree[x].l + Tree[x].r) /2 - Tree[L(x)].rs + 1;
        if (Tree[R(x)].sum >= nu)
             return find(nu, R(x));
        return 0;
 }
         
 int main()
 {
      // FILE* fp = fopen("in.txt", "r");
       int n, m; 
       scanf( "%d %d", &n, &m);
       build(1, n, 1);
       int a, b, c;
       while (m--)
       {
             scanf( "%d", &c);
             if (c == 1)
             {
                   scanf( "%d", &a);
                   int ans = find(a, 1);
                   printf("%d\n", ans); 
                   if (ans)
                      update(ans, ans + a - 1, 1, 1);
             }
             else
             {
                   scanf( "%d %d", &a, &b);
                   update(a, a + b - 1, 0, 1);
             }
       }
     //  getchar();
       return 0;
 } 



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章