zoukankan      html  css  js  c++  java
  • poj 3667 线段树成端更新区间最大连续和

    题目描述:

    输入包括n,m,n表示现在一共有n个相邻的房间,m表示有m条命令。

    1 a 表示现在来了一个人数为a的队伍,需要一个连续的区间能够容纳这么多人,如果能够容纳,输入最靠左边的房间的号码,否则输出0。

    2 a,b  表示清空[a,a+b-1]区间内所有的房子

    解题思路:

       线段树结构体,定义需要记录的三个值,最大左连续、最大右连续、最大连续。

    由上面的图可知,我们现在要更新两端区间,此时,合并区间的最大连续房间数只有三种情况:

    1、  左区间最大连续房间数

    2、  右区间最大连续房间数

    3、  左区间最大右连续房间数 + 右区间最大左连续房间数

    只要能够维护这些值,当中的更新和询问就好办了。

    代码:

    View Code
     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<string.h>
     4 using namespace std;
     5 const int N = 50005;
     6 int mmax[N<<2],lmax[N<<2],rmax[N<<2],cover[N<<2];
     7 void PushDown(int t,int m)
     8 {
     9      if(cover[t]!=-1)
    10      {
    11         cover[t<<1]=cover[t<<1|1]=cover[t];
    12         mmax[t<<1]=lmax[t<<1]=rmax[t<<1]=cover[t]?0:m-(m>>1);
    13         mmax[t<<1|1]=lmax[t<<1|1]=rmax[t<<1|1]=cover[t]?0:(m>>1);
    14         cover[t]=-1;
    15      }
    16 }
    17 void PushUp(int t,int m)
    18 {
    19      lmax[t]=lmax[t<<1];
    20      if(lmax[t]==(m-(m>>1)))lmax[t]+=lmax[t<<1|1];
    21      rmax[t]=rmax[t<<1|1];
    22      if(rmax[t]==(m>>1))rmax[t]+=rmax[t<<1];
    23      mmax[t]=max(mmax[t<<1],mmax[t<<1|1]);
    24      mmax[t]=max(mmax[t],rmax[t<<1]+lmax[t<<1|1]);
    25 }
    26 void build(int t,int l,int r)
    27 {
    28      mmax[t]=lmax[t]=rmax[t]=r-l+1;
    29      cover[t]=-1;
    30      if(l==r) return ;
    31      int m=(l+r)>>1;
    32      build(t<<1,l,m);
    33      build(t<<1|1,m+1,r);
    34 }
    35 int query(int t,int l,int r,int w)
    36 {
    37     if(l==r)return l;
    38     PushDown(t,r-l+1);
    39     int m=(l+r)>>1;
    40     if(mmax[t<<1]>=w)return query(t<<1,l,m,w);
    41     else
    42       if(rmax[t<<1]+lmax[t<<1|1]>=w)return m-rmax[t<<1]+1;
    43     return query(t<<1|1,m+1,r,w);
    44 }
    45 void update(int t,int l,int r,int L,int R,int val)
    46 {
    47     if(L<=l&&r<=R)
    48     {
    49        mmax[t]=lmax[t]=rmax[t]=val?0:r-l+1;
    50        cover[t]=val;
    51        return ;
    52     }
    53     PushDown(t,r-l+1);
    54     int m=(l+r)>>1;
    55     if(L<=m)update(t<<1,l,m,L,R,val);
    56     if(R>m)update(t<<1|1,m+1,r,L,R,val);
    57     PushUp(t,r-l+1);
    58 }
    59 int main()
    60 {
    61     int n,m,o,a,b;
    62     while(scanf("%d%d",&n,&m)!=EOF)
    63     {
    64           build(1,1,n);
    65           for(int i=0;i<m;i++)
    66           {
    67               scanf("%d",&o);
    68               if(o==1)
    69               {
    70                  scanf("%d",&a);
    71                  if(mmax[1]<a)printf("0\n");
    72                  else
    73                  {
    74                       int pos=query(1,1,n,a);
    75                       printf("%d\n",pos);
    76                       update(1,1,n,pos,pos+a-1,1);
    77                  }
    78               }
    79               else
    80               {
    81                  scanf("%d%d",&a,&b);
    82                  update(1,1,n,a,a+b-1,0);
    83               }   
    84           }
    85     }
    86     return 0;    
    87 }
  • 相关阅读:
    路由器安全-FPM
    网络基础设施保护和局域网安全
    DMVPN基础配置
    IPSec的链路和设备备份
    IPSec的高可用性技术
    关于Mobility Express转LAP注意事项
    实际中可能遇到的NAT问题(IPsec)
    NAT-T和PAT(IPSec)
    加密设备NAT对IPSec的影响
    影响IPSec的网络问题
  • 原文地址:https://www.cnblogs.com/nuoyan2010/p/2736064.html
Copyright © 2011-2022 走看看