• poj3667 hotel(线段树区间合并)


    http://poj.org/problem?id=3667

    之前网络赛水过一道区间合并的题 当时是全靠运气试对的 。

    昨天纠结了一晚上也没看出来哪错,改的都跟人家代码一样了还是不对,今天又重新敲了一遍,莫名的就对了,,

    开两个数组分别存这个区间两端点的连续区间 再开一标记数组 用来更新 向上向下都要更新

    View Code
     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 #define N 50010
     7 int s[N<<2],kc[N<<2],lc[N<<2],rc[N<<2];
     8 void build(int l,int r,int w)
     9 {
    10     s[w] = lc[w] = rc[w] = r-l+1;
    11     kc[w] = -1;
    12     if(l==r)
    13     return ;
    14     int m = (l+r)/2;
    15     build(l,m,w<<1);
    16     build(m+1,r,w<<1|1);
    17 }
    18 void pushdown(int w,int c)
    19 {
    20     if(kc[w]!=-1)
    21     {
    22         kc[w<<1] = kc[w<<1|1] = kc[w];
    23         s[w<<1] = lc[w<<1] = rc[w<<1] = kc[w]?0:c-(c>>1);
    24         s[w<<1|1] = lc[w<<1|1] = rc[w<<1|1] = kc[w]?0:c>>1;
    25         kc[w] = -1;
    26     }
    27 }
    28 void pushup(int w,int c)
    29 {
    30     lc[w] = lc[w<<1];
    31     rc[w] = rc[w<<1|1];
    32     if(lc[w]==c-(c>>1))
    33     lc[w]+=lc[w<<1|1];
    34     if(rc[w]==c>>1)
    35     rc[w]+=rc[w<<1];
    36     s[w] = max(rc[w<<1]+lc[w<<1|1],max(s[w<<1],s[w<<1|1]));//找出区间中最长的连续段
    37 }
    38 void update(int a,int b,int c,int l,int r,int w)
    39 {
    40     if(l>=a&&b>=r)
    41     {
    42         s[w] = lc[w] = rc[w] = c?0:r-l+1;
    43         kc[w] = c;
    44         return ;
    45     }
    46     pushdown(w,r-l+1);
    47     int m = (l+r)>>1;
    48     if(a<=m)
    49     update(a,b,c,l,m,w<<1);
    50     if(b>m)
    51     update(a,b,c,m+1,r,w<<1|1);
    52     pushup(w,r-l+1);
    53 }
    54 int query(int c,int l,int r,int w)
    55 {
    56     if(l==r)
    57     return l;
    58     pushdown(w,r-l+1);
    59     int m = (l+r)>>1;
    60     if(s[w<<1]>=c)
    61     return query(c,l,m,w<<1);
    62     else
    63     if(rc[w<<1]+lc[w<<1|1]>=c)//中间段
    64     return m-rc[w<<1]+1;
    65     return query(c,m+1,r,w<<1|1);
    66 }
    67 int main()
    68 {
    69     int i,j,k,n,m,x,d;
    70     cin>>n>>m;
    71     build(1,n,1);
    72     while(m--)
    73     {
    74         cin>>k;
    75         if(k==1)
    76         {
    77             cin>>x;
    78             if(s[1]<x)
    79             printf("0\n");
    80             else
    81             {
    82                 int p = query(x,1,n,1);
    83                 cout<<p<<endl;
    84                 update(p,p+x-1,1,1,n,1);//将这一段更新为已被占
    85             }
    86         }
    87         else
    88         {
    89             cin>>x>>d;
    90             update(x,x+d-1,0,1,n,1);//将这一段更新为空
    91         }
    92     }
    93     return 0;
    94 }
  • 相关阅读:
    vue
    vue
    vue
    vue
    vue
    vue
    vue
    vue
    vue
    vue
  • 原文地址:https://www.cnblogs.com/shangyu/p/2729350.html
Copyright © 2020-2023  润新知