非常细腻的线段树题目啊,后来还是有个细节写错了,查了一个晚上。。就不分析了。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <utility>
#include <cstdlib>
using namespace std;
#define N 80011 struct node
{
int ls,rs,ms;
int pos;
int mark; // 0: unsure 1: all-empty 2: all-full
}tree[*N]; int n,m; void build(int l,int r,int rt)
{
tree[rt].ls = tree[rt].rs = tree[rt].ms = r-l+;
tree[rt].pos = l;
if(l == r)
{
return;
}
int mid = (l+r)/;
build(l,mid,*rt);
build(mid+,r,*rt+);
} int if_all_empty(int l,int r,int rt)
{
if(tree[rt].ls == r-l+)
return ;
return ;
} void update(int l,int r,int rt)
{
if(!tree[rt].mark)
return;
if(tree[rt].mark == ) //全空,则下传给左右子树
{
int len = r-l+;
tree[*rt].ls = tree[*rt].rs = tree[*rt].ms = (len+)/;
tree[*rt].pos = l;
tree[*rt+].ls = tree[*rt+].rs = tree[*rt+].ms = len/;
tree[*rt+].pos = (l+r)/+;
tree[*rt].mark = tree[*rt+].mark = ;
}
else if(tree[rt].mark == ) //全满,则下传给左右子树
{
tree[*rt].ls = tree[*rt].rs = tree[*rt].ms = ;
tree[*rt].pos = l;
tree[*rt+].ls = tree[*rt+].rs = tree[*rt+].ms = ;
tree[*rt+].pos = (l+r)/+;
tree[*rt].mark = tree[*rt+].mark = ;
}
tree[rt].mark = ; // not "== 0"
} int query(int l,int r,int dis,int rt)
{
update(l,r,rt);
if(tree[rt].ms<dis)
return ;
if(tree[rt].ms == dis)
return tree[rt].pos;
int mid = (l+r)/;
if(tree[*rt].ms>=dis)
return query(l,mid,dis,*rt);
if(tree[*rt].rs + tree[*rt+].ls>=dis)
return mid - tree[*rt].rs + ;
return query(mid+,r,dis,*rt+);
} void in_out(int l,int r,int aa,int bb,int flag,int rt) //flag == 1: insert else quit
{
if(aa>r||bb<l)
return;
if(aa<=l&&bb>=r)
{
if(flag == ) //如果当前要入住
{
tree[rt].ls = tree[rt].rs = tree[rt].ms = ;
tree[rt].pos = l;
tree[rt].mark = ;
}
else //如果当前要退房
{
tree[rt].ls = tree[rt].rs = tree[rt].ms = r-l+;
tree[rt].pos = l;
tree[rt].mark = ;
}
return;
}
update(l,r,rt);
int mid = (l+r)/;
in_out(l,mid,aa,bb,flag,*rt);
in_out(mid+,r,aa,bb,flag,*rt+); tree[rt].ls = tree[*rt].ls;
if(if_all_empty(l,mid,*rt))
tree[rt].ls += tree[*rt+].ls;
tree[rt].rs = tree[*rt+].rs;
if(if_all_empty(mid+,r,*rt+))
tree[rt].rs += tree[*rt].rs; tree[rt].ms = max(tree[*rt].rs+tree[*rt+].ls,max(tree[*rt].ms,tree[*rt+].ms)); if(tree[rt].ms == tree[*rt].ms) //如果当前区间最大空房数等于左子树最大空房数
tree[rt].pos = tree[*rt].pos; //则起点置为左子树的起点 else if(tree[rt].ms == tree[*rt].rs + tree[*rt+].ls) //同理
tree[rt].pos = mid - tree[*rt].rs + ; else
tree[rt].pos = tree[*rt+].pos;
} int main()
{
scanf("%d%d",&n,&m);
memset(tree,,sizeof(tree));
build(,n,);
int i,flag;
int x,dis;
for(i=;i<m;i++)
{
scanf("%d",&flag);
if(flag == )
{
scanf("%d",&dis);
int ans = query(,n,dis,);
printf("%d\n",ans);
if(ans)
in_out(,n,ans,ans+dis-,,);
}
else if(flag == )
{
scanf("%d%d",&x,&dis);
in_out(,n,x,x+dis-,,);
}
}
return ;
}

UESTC 1227 & POJ 3667 Hotel的更多相关文章

  1. 线段树(区间合并) POJ 3667 Hotel

    题目传送门 /* 题意:输入 1 a:询问是不是有连续长度为a的空房间,有的话住进最左边 输入 2 a b:将[a,a+b-1]的房间清空 线段树(区间合并):lsum[]统计从左端点起最长连续空房间 ...

  2. POJ 3667 Hotel(线段树)

    POJ 3667 Hotel 题目链接 题意:有n个房间,如今有两个操作 1.找到连续长度a的空房间.入住,要尽量靠左边,假设有输出最左边的房间标号,假设没有输出0 2.清空[a, a + b - 1 ...

  3. poj 3667 Hotel (线段树)

    http://poj.org/problem?id=3667 Hotel Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 94 ...

  4. POJ 3667 Hotel (线段树区间合并)

    题目链接:http://poj.org/problem?id=3667 最初给你n间空房,m个操作: 操作1 a 表示检查是否有连续的a间空房,输出最左边的空房编号,并入住a间房间. 操作2 a b ...

  5. POJ 3667 Hotel(线段树+区间合并)

    http://poj.org/problem?id=3667 题意: 有N个房间,M次操作.有两种操作(1)"1a",表示找到连续的长度为a的空房间,如果有多解,优先左边的,即表示 ...

  6. POJ 3667 Hotel (线段树区间合并)

    题目链接:http://poj.org/problem?id=3667 题目大意:一共有n个房间,初始时都是空的,现在有m个操作,操作有以下两种: 1.1 d :询问是否有连续d个空的房间,若有则输出 ...

  7. POJ 3667 Hotel(线段树 区间合并)

    Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...

  8. poj 3667 Hotel(线段树,区间合并)

    Hotel Time Limit: 3000MSMemory Limit: 65536K Total Submissions: 10858Accepted: 4691 Description The ...

  9. (简单) POJ 3667 Hotel,线段树+区间合并。

    Description The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and e ...

随机推荐

  1. 设置让ASP.NET管道接收所有类型的请求

    在web.config文件添加如下一段配置: <configuration> <system.webServer> <modules runAllManagedModul ...

  2. javascript --- 将共享属性迁移到原型中去

    当我们用一个构造函数创建对象时,其属性就会被添加到this中去.并且被添加到this中的属性实际上不会随着实体发生改变,这时,我们这种做法显得会很没有效率.例如: function her(){ th ...

  3. VS2015发布Webservice

    第一步:开启IIs:在控制面板程序——>程序功能——>打开或关闭windows功能,把“Internet信息服务”下面的“FTP服务器”.“Web管理工具”.“万维网服务”全部勾上,然后点 ...

  4. 安卓开发_浅谈ContextMenu(上下文菜单)

    长下文菜单,即长按view显示一个菜单栏 与OptionMenu的区别OptionMenu对应的是activity,一个activity只能拥有一个选项菜单ContextMenu对应的是View,每个 ...

  5. i++是否原子操作

    i++是否原子操作 不是原子操作.理由: 1.i++分为三个阶段: 内存到寄存器 寄存器自增 回内存 这三个阶段中间都可以被中断分离开.  2.++i首先要看编译器是怎么编译的, 某些编译器比如VC在 ...

  6. MyBatis入门(七)---逆向工程

    一.逆向工程 1.1.概述 mybatis需要程序号自己编写的SQL. mybatis官方提供了逆向工程,可以针对单表自动生成mybatis执行所需要的代码 (mapper,java,maper.xm ...

  7. 解决虚拟机linux端mysql数据库无法远程访问

    解决虚拟机linux端mysql数据库无法远程访问 1. 在控制台执行 mysql -u root -p mysql,CentOS系统提示输入数据库root用户的密码,输入完成后即进入mysql控制台 ...

  8. 2、IOS开发--iPad之仿制QQ空间 (初始化HomeViewController子控件视图)

    1.先初始化侧边的duck,效果图: 实现步骤: 2.然后初始化BottomMenu,效果: 步骤: 其实到这里,会出现一个小bug,那就是: 子控件的位置移高了,主要原因是: 逻辑分析图: 问题解决 ...

  9. 多线程基础(六)GCD基础

    更多值得学习的GCD知识,可以学习: Grand Central Dispatch (GCD) Reference GCDObjC 1.GCD的基本概念     什么是GCD 全称是Grand Cen ...

  10. select_tag 选择后自动提交,并且保持选择的项

    使用select来选择,,,选择就响应真是花了好大的功夫....你妹...在controller设置变量来储存选择后的值...js中如果select选择为空那么传入的值是””而不是null selec ...