博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【转】poj 1823 hotel 线段树【Good】
阅读量:5936 次
发布时间:2019-06-19

本文共 3160 字,大约阅读时间需要 10 分钟。

题意:一个hotel,有n个连续的房间,开始时均无人住宿

共有3种操作

1 a b 从a开始连续b个房间全部旅客住宿 [a,a+b-1];

2 a b 从a开始连续b个房间全部旅客离开 [a,a+b-1];

3 查询最长连续空房间

思路:线段树,记录每个节点,左边,右边各最多连续空房间lmax,rmax; 以及这个区间内最多空房间max

#include<iostream>

 #include<cmath>
 using namespace std;
 #define MAXN 16001
 struct node
 {
     int lmax,rmax,max;
     int left,right;
     int flag;//0:全空;1:全部被占用;2:部分被占用
 };
 node tree[MAXN*4];
 void build(int i)
 {
     tree[i].lmax=tree[i].rmax=tree[i].max=tree[i].right-tree[i].left+1;//当前节点的max,lmax和rmax都初始化为right-left+1
     tree[i].flag=0;
     if(tree[i].left==tree[i].right) return ;
     int mid=(tree[i].left+tree[i].right)/2;
     tree[2*i].left=tree[i].left; tree[2*i].right=mid;
     tree[2*i+1].left=mid+1; tree[2*i+1].right=tree[i].right;
     build(2*i); build(2*i+1);
 }
 
 void insert(int i,int x,int y,int c)
 {
     //cout<<i<<" "<<x<<" "<<y<<" "<<c<<" "<<tree[i].left<<" "<<tree[i].right<<endl;
     if(tree[i].left==x&&tree[i].right==y)
     {
         tree[i].flag=c;
         if(c==1) tree[i].lmax=tree[i].rmax=tree[i].max=0;
         else tree[i].lmax=tree[i].rmax=tree[i].max=tree[i].right-tree[i].left+1;
         return;
     }

   //当前节点完全递归返回前未被占用,保证“当前节点的子节点的状态被标记为0”优先级最高

   //具体解析:因为之前操作中的插入或者删除操作都是到达满足if(tree[i].left==x&&tree[i].right==y)的条件之后就返回了,

   //但是我们之后要进行的插入和删除操作要是区段有可能比之前涉及到的区段小,这个时候在递归之前判断当前节点状态并且

   //对相应左子树和右子树执行更新操作就很有必要了

     if(tree[i].flag==0)
     {
         tree[2*i].flag=tree[2*i+1].flag=0;

   //左右子树的各个最长子段都设为right-left+1

         tree[2*i].lmax=tree[2*i].rmax=tree[2*i].max=tree[2*i].right-tree[2*i].left+1;
         tree[2*i+1].lmax=tree[2*i+1].rmax=tree[2*i+1].max=tree[2*i+1].right-tree[2*i+1].left+1;
     }

   //当前节点递归返回前完全被占用,保证“当前节点的子节点的状态被标记为1”优先级最高(具体解析同上)

     if(tree[i].flag==1)
     {  
         tree[2*i].flag=tree[2*i+1].flag=1;
   //左右子树的各个最长子段都设为0
         tree[2*i].lmax=tree[2*i].rmax=tree[2*i].max=0;
         tree[2*i+1].lmax=tree[2*i+1].rmax=tree[2*i+1].max=0;
     }
  //递归操作
     int mid=(tree[i].left+tree[i].right)/2;
     if(y<=mid) insert(2*i,x,y,c);
     else if(x>mid) insert(2*i+1,x,y,c);
     else
     {
         insert(2*i,x,mid,c);
         insert(2*i+1,mid+1,y,c);
     }
  //延迟处理,更新当前节点的状态
     if(tree[2*i].flag==0&&tree[2*i+1].flag==0)//左右子树均全空
     {
         tree[i].flag=0;
         tree[i].lmax=tree[i].rmax=tree[i].max=tree[i].right-tree[i].left+1;
     }
     else if(tree[2*i].flag==0&&tree[2*i+1].flag==1)//左子树全空,右子树全被占用
     {
         tree[i].flag=2;
         tree[i].lmax=tree[i].max=tree[2*i].max;
         tree[i].rmax=0;
     }
     else if(tree[2*i].flag==1&&tree[2*i+1].flag==0)//左子树被占用,右子树全空
     {
         tree[i].flag=2;
         tree[i].rmax=tree[i].max=tree[2*i+1].max;
         tree[i].lmax=0;
     }
     else if(tree[2*i].flag==1&&tree[2*i+1].flag==1)//左右子树都全被占用
     {
         tree[i].flag=1;       
         tree[i].lmax=tree[i].rmax=tree[i].max=0;  
     }
     else//左子树或者右子树含有部分被占用的情况
     {
         tree[i].flag=2;
         tree[i].max=max(tree[2*i].max,tree[2*i+1].max);
         tree[i].max=max(tree[i].max,tree[2*i].rmax+tree[2*i+1].lmax);
         if(tree[2*i].flag==0)

                 tree[i].lmax=tree[2*i].max+tree[2*i+1].lmax;

         else

                  tree[i].lmax=tree[2*i].lmax;

         if(tree[2*i+1].flag==0)

      tree[i].rmax=tree[2*i].rmax+tree[2*i+1].max;

         else

                 tree[i].rmax=tree[2*i+1].rmax;

     }
 } 
 int main()
 {
     int n,m;
     scanf("%d%d",&n,&m);
     tree[1].left=1; tree[1].right=n;
     build(1);
     int i;
     int x,y,c;
     for(i=1;i<=m;i++)
     {
         scanf("%d",&c);
         if(c==3) printf("%d\n",tree[1].max);
         if(c==1)
         {
             scanf("%d%d",&x,&y);
             insert(1,x,x+y-1,1);
         }
         if(c==2)
         {
             scanf("%d%d",&x,&y);
             insert(1,x,x+y-1,0);
         }
     }
     return 0;
 }

转载于:https://www.cnblogs.com/lzhitian/archive/2012/07/28/2612647.html

你可能感兴趣的文章
iOS项目质量管理自动化
查看>>
Android 记录
查看>>
html----rem结合vw布局
查看>>
Apache——DBUtils框架ResultSetHandler接口使用
查看>>
隐藏发料权限
查看>>
检查装配件属性
查看>>
H2数据库攻略
查看>>
java数组及数组的插入,删除,冒泡算法
查看>>
C# gridview分頁導出excel
查看>>
iOS多线程编程之创建线程安全(转载)
查看>>
for循环
查看>>
as3 垃圾回收机制
查看>>
command not found Operation not permitted
查看>>
Mybatis的配置文件和映射文件详解
查看>>
react 如何 阻止冒泡
查看>>
vue2.X 与 vue1.X 的区别
查看>>
nohup & 及端口查看
查看>>
ffmpeg 的log 获取办法
查看>>
rtmp流媒体协议播放遇到的坑
查看>>
Go 之旅四: 方法与接口篇
查看>>