POJ 3667 Hotel (线段树区间合并)
题目链接:http://poj.org/problem?id=3667
最初给你n间空房,m个操作:
操作1 a 表示检查是否有连续的a间空房,输出最左边的空房编号,并入住a间房间。
操作2 a b 表示将编号为a之后的b间房间清空。
典型的区间合并问题,这位大牛讲的更清楚:http://www.cnblogs.com/yewei/archive/2012/05/05/2484471.html
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 5e4 + ;
//sum表示这个区间的最大数,lsum表示从这个区间最左边开始连续的最大数,rsum与lsum方向相反
struct data {
int l , r , lsum , rsum , sum , cover;
}T[MAXN << ]; void build(int p , int l , int r) {
int mid = (l + r) >> ;
T[p].lsum = T[p].rsum = T[p].sum = r - l + ;
T[p].cover = -;
T[p].l = l , T[p].r = r;
if(l == r)
return ;
build(p << , l , mid);
build((p << )| , mid + , r);
} void Pushdown(int p) {
if(T[p].cover != -) {
int ls = p << , rs = (p << )|;
T[ls].cover = T[rs].cover = T[p].cover;
T[ls].lsum = T[ls].rsum = T[ls].sum = T[p].cover ? : T[ls].r - T[ls].l + ;
T[rs].lsum = T[rs].rsum = T[rs].sum = T[p].cover ? : T[rs].r - T[rs].l + ;
T[p].cover = -;
}
} void Pushup(int p) {
T[p].lsum = T[p << ].lsum;
T[p].rsum = T[(p << )|].rsum;
if(T[p].lsum == T[p << ].r - T[p << ].l + )
T[p].lsum += T[(p << )|].lsum;
if(T[p].rsum == T[(p << )|].r - T[(p << )|].l + )
T[p].rsum += T[p << ].rsum;
int temp = max(T[(p << )|].sum , T[p << ].rsum + T[(p << )|].lsum);
T[p].sum = max(T[p << ].sum , temp);
} int query(int p , int len) {
int mid = (T[p].l + T[p].r) >> ;
if(T[p].l == T[p].r) {
return T[p].l;
}
Pushdown(p);
if(T[p << ].sum >= len) { //左孩子区间的最大数,优先选左孩子
return query(p << , len);
}
else if(T[p << ].rsum + T[(p << )|].lsum >= len) { //其次要是左孩子的rsum和右孩子的lsum 加起来大于len
return mid - T[p << ].rsum + ;
}
else {
return query((p << )| , len); //最后就是右孩子
}
} void updata(int p , int l , int r , int flag) {
int mid = (T[p].l + T[p].r) >> ;
if(T[p].l == l && T[p].r == r) {
T[p].sum = T[p].lsum = T[p].rsum = flag ? : r - l + ;
T[p].cover = flag;
return ;
}
Pushdown(p);
if(r <= mid) {
updata(p << , l , r , flag);
}
else if(l > mid) {
updata((p << )| , l , r , flag);
}
else {
updata(p << , l , mid , flag);
updata((p << )| , mid + , r , flag);
}
Pushup(p);
} int main()
{
int n , m , choose , u , v;
while(~scanf("%d %d" , &n , &m)) {
build( , , n);
while(m--) {
scanf("%d" , &choose);
if(choose == ) {
scanf("%d" , &u);
if(T[].sum < u)
printf("0\n");
else {
int pos = query( , u);
printf("%d\n" , pos);
updata( , pos , pos + u - , );
}
}
else {
scanf("%d %d" , &u , &v);
updata( , u , min(u + v - , n) , );
}
}
}
return ;
}
POJ 3667 Hotel (线段树区间合并)的更多相关文章
- POJ 3667 Hotel(线段树 区间合并)
Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...
- POJ 3667 & 1823 Hotel (线段树区间合并)
两个题目都是用同一个模板,询问最长的连续未覆盖的区间 . lazy代表是否有人,msum代表区间内最大的连续长度,lsum是从左结点往右的连续长度,rsum是从右结点往左的连续长度. 区间合并很恶心啊 ...
- poj 3667 Hotel (线段树)
http://poj.org/problem?id=3667 Hotel Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 94 ...
- poj 3667 Hotel(线段树,区间合并)
Hotel Time Limit: 3000MSMemory Limit: 65536K Total Submissions: 10858Accepted: 4691 Description The ...
- 线段树(区间合并) POJ 3667 Hotel
题目传送门 /* 题意:输入 1 a:询问是不是有连续长度为a的空房间,有的话住进最左边 输入 2 a b:将[a,a+b-1]的房间清空 线段树(区间合并):lsum[]统计从左端点起最长连续空房间 ...
- Poj 3667——hotel——————【线段树区间合并】
Hotel Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 13124 Accepted: 5664 Descriptio ...
- poj3667 Hotel (线段树 区间合并)
poj3667 HotelTime Limit: 3000MS Memory Limit: 65536KTotal Submissions: 18925 Accepted: 8242Descripti ...
- 【bzoj1593】[Usaco2008 Feb]Hotel 旅馆 线段树区间合并
题目描述 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大的旅馆一共有N (1 <= N & ...
- POJ 2482 Stars in Your Window (线段树区间合并+扫描线)
这题开始一直被矩形框束缚了,想法一直都是枚举线,但是这样枚举都需要O(n^2)...但是看了别人的思路,感觉这题思想真心很好(PS:开头好浪漫的描述啊,可惜并没有什么用) 题意就是在平面上给你一些星 ...
随机推荐
- UVa 10596 Moring Walk【欧拉回路】
题意:给出n个点,m条路,问能否走完m条路. 自己做的时候= =三下两下用并查集做了交,WA了一发-后来又WA了好几发--(而且也是判断了连通性的啊) 搜了题解= = 发现是这样的: 因为只要求走完所 ...
- ti processor sdk linux am335x evm /bin/setup-targetfs-nfs.sh hacking
#!/bin/sh # # ti processor sdk linux am335x evm /bin/setup-targetfs-nfs.sh hacking # 说明: # 本文主要对TI的s ...
- LeetCode Contains Duplicate (判断重复元素)
题意: 如果所给序列的元素不是唯一的,则返回true,否则false. 思路: 哈希map解决. class Solution { public: bool containsDuplicate(vec ...
- C# C/S 结构操作Ini系统文件
Winfrom 开发时,有时会将一些系统某个设置保存到Ini 类型的文件中.下面提供操作Ini 文件的代码: public static class IniFiles { [DllImport(&qu ...
- wifi详解(三)
1 WLAN驱动结构介绍 1.1 SDIO驱动 在drivers/mmc下面是mmc卡,SD卡和SDIO卡驱动部分,其中包括host驱动,card驱动和core部分,由于网络接 ...
- 音频PCM格式
经常见到这样的描述: 44100HZ 16bit stereo 或者 22050HZ 8bit mono 等等. 44100HZ 16bit stereo: 每秒钟有 44100 次采样, 采样数据用 ...
- POJ 1716 Integer Intervals
题意:给出一些区间,求一个集合的长度要求每个区间里都至少有两个集合里的数. 解法:贪心或者差分约束.贪心的思路很简单,只要将区间按右边界排序,如果集合里最后两个元素都不在当前区间内,就把这个区间内的最 ...
- 用javascript 面向对象制作坦克大战(四)
我们现在还差一个重要的功能,没错,敌人坦克的创建以及子弹击中敌人坦克时的碰撞检测功能. 5. 创建敌人坦克完成炮弹碰撞检测 5.1 创建敌人坦克对象 敌人坦克和玩家坦克一样,同样继承自我们的坦克 ...
- 【windows核心编程】一个API拦截的例子
API拦截 修改PE文件导入段中的导入函数地址 为 新的函数地址 这涉及PE文件格式中的导入表和IAT,PE文件中每个隐式链接的DLL对应一个IMAGE_IMPORT_DESCRIPTOR描述符结构, ...
- C#复习反射
反射中常用方法: //获取对象类型 One one = new One(); Type t = one.GetType(); //动态加载 Assembly a = Assembly.LoadFile ...