【线段树区间合并】POJ3667-Hotel
【题意】
一段区间初始均为可行。有两个操作:
1→找出长度为w的一段可行区间,如果存在则返回这个可行区间最靠左的情况,并将该区间设为不可行;
2→将区间[a,b]设为可行区间。
【思路】
经典的线段树合并,代码依旧用的是神犇的线段树模板。详见注释。
【错误点】
延迟标记的时候,忘记把cover清为-1了,导致RE!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int MAXN=+;
int cover[MAXN<<];//-1表示当前没有覆盖标记,1表示均覆盖为不可行,0表示均覆盖为可行
int lsum[MAXN<<];//该区间从左起连续的可用区间长度的最大值
int msum[MAXN<<];//该区间中连续的可用区间长度的最大值
int rsum[MAXN<<];//该区间从右起连续的可用区间长度的最大值 void PushUp(int rt,int m)
{
lsum[rt]=lsum[rt<<];
if (lsum[rt]==m-(m>>)) lsum[rt]+=lsum[rt<<|];
/*如果左孩子全部为可用区间,那么加上右孩子的左端*/
rsum[rt]=rsum[rt<<|];
if (rsum[rt]==m>>) rsum[rt]+=rsum[rt<<];
/*同上*/
msum[rt]=max(max(msum[rt<<],msum[rt<<|]) , rsum[rt<<]+lsum[rt<<|]);
/*该区间的可用区间可能是:左孩子最大的可用区间、有孩子最大的可用区间,和跨越左右孩子加在一起的可用区间*/
} void PushDown(int rt,int m)
{
if (cover[rt]!=-)
{
cover[rt<<]=cover[rt<<|]=cover[rt];
if (cover[rt]==)
{
msum[rt<<]=lsum[rt<<]=rsum[rt<<]=;
msum[rt<<|]=lsum[rt<<|]=rsum[rt<<|]=;
}
else
{
msum[rt<<]=lsum[rt<<]=rsum[rt<<]=m-(m>>);
msum[rt<<|]=lsum[rt<<|]=rsum[rt<<|]=m>>;
}
cover[rt]=-;
/*千万不要忘记将rt清为-1*/
}
} int query(int w,int l,int r,int rt)
{
if (l==r) return l;
PushDown(rt,r-l+);
int m=(l+r)>>;
if (msum[rt<<]>=w) return(query(w,lson));
/*由于要找最左边的区间,按照左孩子、跨越两者、有孩子的顺序查找*/
if (rsum[rt<<]+lsum[rt<<|]>=w) return(m-rsum[rt<<]+);
return(query(w,rson));
} void update(int L,int R,int o,int l,int r,int rt)
{
if (L<=l && r<=R)
{
cover[rt]=o;
if (o==) msum[rt]=lsum[rt]=rsum[rt]=;
else msum[rt]=lsum[rt]=rsum[rt]=r-l+;
return;
}
PushDown(rt,r-l+);//这里是l和r,不要写成L和R
int m=(l+r)>>;
if (L<=m) update(L,R,o,lson);
if (m<R) update(L,R,o,rson);
PushUp(rt,r-l+);
} void build(int l,int r,int rt)
{
msum[rt]=lsum[rt]=rsum[rt]=r-l+;
cover[rt]=-;
if (l==r) return;
int m=(l+r)>>;
build(lson);
build(rson);
} int main()
{
int n,m;
scanf("%d%d",&n,&m);
build(,n,);
for (int i=;i<m;i++)
{
int op;
scanf("%d",&op);
if (op==)
{
int w;
scanf("%d",&w);
if (msum[]<w) cout<<<<endl;
/*如果根的可用区间已经小于w,那么一定是找不到长度为w的可用区间*/
else
{
int p=query(w,,n,);
cout<<p<<endl;
update(p,p+w-,,,n,);
}
}
else
{
int u,v;
scanf("%d%d",&u,&v);
update(u,u+v-,,,n,);
}
}
return ;
}
【线段树区间合并】POJ3667-Hotel的更多相关文章
- poj3667 Hotel (线段树 区间合并)
poj3667 HotelTime Limit: 3000MS Memory Limit: 65536KTotal Submissions: 18925 Accepted: 8242Descripti ...
- POJ 3667 Hotel(线段树 区间合并)
Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...
- 线段树(区间合并) 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 线段树 区间合并
//Accepted 3728 KB 1079 ms //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...
- poj-3667(线段树区间合并)
题目链接:传送门 参考文章:传送门 思路:线段树区间合并问题,每次查询到满足线段树的区间最左值,然后更新线段树. #include<iostream> #include<cstdio ...
- 【bzoj1593】[Usaco2008 Feb]Hotel 旅馆 线段树区间合并
题目描述 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大的旅馆一共有N (1 <= N & ...
- HDU 3911 线段树区间合并、异或取反操作
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...
- HDU 3911 Black And White(线段树区间合并+lazy操作)
开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...
- HYSBZ 1858 线段树 区间合并
//Accepted 14560 KB 1532 ms //线段树 区间合并 /* 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[ ...
随机推荐
- js 合并多个对象 Object.assign
Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象.它将返回目标对象. var o1 = { a: 1 };var o2 = { b: 2 };var o3 ...
- C#编写程序监测某个文件夹内是否有文件进行了增,删,改的动作?
新建一个Console应用程序,项目名称为“FileSystemWatcher”,Copy代码进,编译后就可以用了.代码如下: using System; using System.Collectio ...
- javascript 变量类型判断
一.typeof 操作符 对于Function, String, Number ,Undefined 等几种类型的对象来说,他完全可以胜任,但是为Array时 "); typeof arr ...
- js删除数组中重复的元素
1.方法一 将数组逐个搬到另一个数组中,当遇到重复元素时,不移动,若元素不重复则移动到新数组中 function unique(arr){ var len = arr.length; var resu ...
- Java面向对象的三个特征与含义
封装 1.英文为 encapsulation,实现信息隐藏: 2.把同一类事物的特性归纳到一个类中(属性和行为),隐藏对象的内部实现: 继承 1.英文为 inheritance: 2.继承的过程,是从 ...
- python近期遇到的一些面试问题(二)
1. 解释什么是栈溢出,在什么情况下可能出现. 栈溢出是由于C语言系列没有内置检查机制来确保复制到缓冲区的数据不得大于缓冲区的大小,因此当这个数据足够大的时候,将会溢出缓冲区的范围.在Python中, ...
- 【bzoj3786】星系探索
ETT模版题. 真正的Eular-Tour-Tree维护的是树的欧拉序. 由于各种原因,没人知道怎么维护欧拉序,所以我写的是个假的,维护dfs序的. 本质还是用Splay维护序列. 然后因为我常数太差 ...
- git配置服务器版仓库
1.git 可以使用四种主要的协议来传输数据:本地传输,SSH 协议,Git 协议和 HTTP 协议.现在使用360同步盘同步一个网络的仓库管理. 2.查看设置好的360同步盘的文件 3.创建空的仓库 ...
- 使用Storm实现实时大数据分析(转)
原文链接:http://blog.csdn.net/hguisu/article/details/8454368 简单和明了,Storm让大数据分析变得轻松加愉快. 当今世界,公司的日常运营经常会生成 ...
- leetcode 之Swap Nodes in Pairs(21)
不允许通过值来交换,在更新指针时需要小心. ListNode *swapNodes(ListNode* head) { ListNode dummy(-); dummy.next = head; fo ...