PKU 3667 Hotel (线段树,区间合并,最长连续区间)
题意:宾馆有N个房间(1~N),M个操作,a=1,输入b,表示N间房是否有连续的b间房。有输出最左边的房编号
没有输出0。a=2,输入b,c表示房间b到c清空。
模仿了大神的代码,敲了一遍,有些地方还要深入了解。
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
#include <math.h>
#define M 50001
#define eps 1e-6
#define LL long long
using namespace std; struct node
{
int left,right;
int lsum,rsum,msum;
int lazy;
}tree[M*3]; void push_up(int id)
{
int ll=tree[id<<1].right-tree[id<<1].left+1;
int rr=tree[id<<1|1].right-tree[id<<1|1].left+1;
tree[id].lsum=tree[id<<1].lsum;
if(tree[id<<1].lsum==ll)
tree[id].lsum+=tree[id<<1|1].lsum;
tree[id].rsum=tree[id<<1|1].rsum;
if(tree[id].rsum==rr)
tree[id].rsum+=tree[id<<1].rsum;
tree[id].msum = max(max(tree[id<<1].msum,tree[id<<1|1].msum),tree[id<<1].rsum+tree[id<<1|1].lsum);
}
void push_down(int id)
{
if(tree[id].lazy!=-1)
{
int ll=tree[id<<1].right-tree[id<<1].left+1;
int rr=tree[id<<1|1].right-tree[id<<1|1].left+1;
tree[id<<1].lazy=tree[id<<1|1].lazy=tree[id].lazy;
tree[id].lazy=-1;
tree[id<<1].rsum = tree[id<<1].lsum = tree[id<<1].msum = tree[id<<1].lazy ? 0:ll;
tree[id<<1|1].rsum = tree[id<<1|1].lsum = tree[id<<1|1].msum = tree[id<<1|1].lazy ?0:rr;
}
}
void build(int id,int l,int r)
{
tree[id].left=l;tree[id].right=r;
tree[id].lsum=tree[id].rsum=tree[id].msum=(r-l+1);
tree[id].lazy=-1;
if(l==r)
return ;
int mid=(l+r)/2;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
//push_up(id);
} void update(int id,int l,int r,int c)
{
if(tree[id].left==l&&tree[id].right==r)
{
tree[id].lsum=tree[id].rsum=tree[id].msum=c?0:(r-l+1);
tree[id].lazy=c;
return ;
}
push_down(id);
int mid=(tree[id].left+tree[id].right)/2;
if(r<=mid) update(id<<1,l,r,c);
else if(l>mid) update(id<<1|1,l,r,c);
else
{
update(id<<1,l,mid,c);
update(id<<1|1,mid+1,r,c);
}
push_up(id);
}
int query(int id,int v)
{
if(tree[id].left==tree[id].right) return tree[id].left;
push_down(id);
int mid=(tree[id].left+tree[id].right)/2;
if(tree[id<<1].msum>=v)//假设左子树的最大连续空>=需求量。那么直接进入左子树,=也去左子树的原因是题目要求的最左
return query(id<<1,v);
else if(tree[id<<1].rsum+tree[id<<1|1].lsum>=v)//左子树的连续右+右子树的连续左>=w,说明找到了能够直接求出
return mid-tree[id<<1].rsum+1;
return query(id<<1|1,v);
} int main()
{ int n,m;
while(~scanf("%d%d",&n,&m))
{
int a,b,c;
build(1,1,n);
while(m--)
{
scanf("%d",&a);
if(a==1)
{
scanf("%d",&c);
if(tree[1].msum<c) printf("0\n");//根节点的最大连续空间不够
else
{
int p=query(1,c);
printf("%d\n",p);
update(1,p,p+c-1,1);//把这段更新为被覆盖
}
}
else
{
scanf("%d%d",&b,&c);
update(1,b,b+c-1,0);//把这段更新为未被覆盖
}
}
}
return 0;
} /*
10 6
1 3
1 3
1 3
1 3
2 5 5
1 6
*/
PKU 3667 Hotel (线段树,区间合并,最长连续区间)的更多相关文章
- POJ 3667 Hotel(线段树 区间合并)
Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...
- POJ 3667 Hotel (线段树区间合并)
题目链接:http://poj.org/problem?id=3667 最初给你n间空房,m个操作: 操作1 a 表示检查是否有连续的a间空房,输出最左边的空房编号,并入住a间房间. 操作2 a b ...
- POJ 3667 & 1823 Hotel (线段树区间合并)
两个题目都是用同一个模板,询问最长的连续未覆盖的区间 . lazy代表是否有人,msum代表区间内最大的连续长度,lsum是从左结点往右的连续长度,rsum是从右结点往左的连续长度. 区间合并很恶心啊 ...
- PKU 3667 Hotel(线段树)
Hotel The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a ...
- 线段树(区间合并) 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-3667(线段树区间合并)
题目链接:传送门 参考文章:传送门 思路:线段树区间合并问题,每次查询到满足线段树的区间最左值,然后更新线段树. #include<iostream> #include<cstdio ...
- HDU 3911 线段树区间合并、异或取反操作
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...
随机推荐
- NPOI 导出Excel 2007, 2013问题
NPOI默认有两个命名空间HSSF为Excel 2003 版本,若导出2007 及以上后缀名打开excel 则会报错,NPOI也提供了一个07及以上的版本空间XSSF,具体操作列下: NPOI.XSS ...
- Spring Boot (29) 定时任务
使用场景:数据定时增量同步,定时发送邮件,爬虫定时抓取 定时任务概述 定时任务:顾名思义就是在特定/指 定的时间进行工作,比如我们的手机闹钟,他就是一种定时的任务. 实现方式: 1.Timer:JDK ...
- Spring.Net学习笔记(6)-方法注入
一.开发环境 系统:win10 编译器:VS2013 二.涉及程序集 Spring.Core.dll 1.3.1 Common.Logging.dll 三.开发过程 1.项目结构 2.编写Mobile ...
- 在计算机视觉与人工智能领域,顶级会议比SCI更重要(内容转)
很多领域,SCI是王道,尤其在中国,在教师科研职称评审和学生毕业条件中都对SCI极为重视,而会议则充当了补充者的身份.但是在计算机领域,尤其是人工智能与机器学习领域里,往往研究者们更加青睐于会议 我无 ...
- jquery滚轮事件
// jquery 兼容的滚轮事件 $(document).on("mousewheel DOMMouseScroll", function (e) { var delta = ( ...
- 人人都能读懂的css3 3d小demo
css3 3d案例总结 最近入坑 Web 动画,所以把自己的学习过程记录一下分享给大家.就把最近做的比较好的给大家分享下 1.旋转拼图 首先看下效果 代码主要由HTML和CSS3组成,应该说还是比较简 ...
- Java反射机制实战——字段篇
首先,我们来认识几个类. Class(java.lang.Class) Class对象是一个特殊对象,每一个类都有一个Class对象,用来创建该类的“常规”对象.可以通过对象的getClass()方法 ...
- iOS设计模式——Category和 Extension
什么是Category Category模式用于向已经存在的类添加方法从而达到扩展已有类的目的,在很多情形下Category也是比创建子类更优的选择.新添加的方法同样也会被被扩展的类的所有子类自动继承 ...
- Jmeter之关联——常用提取器
Jmeter关联 所谓关联,从业务角度讲,即:某些操作步骤与其相邻步骤存在一定的依赖关系,导致某个步骤的输入数据来源于上一步的返回数据,这时就需要“关联”来建立步骤之间的联系. 简单来说,就是:将上一 ...
- wpf mvvm模式下 在ViewModel关闭view
本文只是博主用来记录笔记,误喷 使用到到了MVVM中消息通知功能 第一步:在需要关闭窗体中注册消息 public UserView() { this.DataContext = new UserVie ...