poj3667---Hotel 线段树区间合并,区间更新
题意:有N个房间,M次操作。有两种操作(1)"1 a",表示找到连续的长度为a的空房间,如果有多解,优先左边的,即表示入住。(2)"2 b len",把起点为b长度的len的房间清空,即退房。三个数组分别记录 lsum区间左值 rsum区间右值 sum区间最大值。
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const double eps = 1e-;
template <class T>
inline bool scan_d(T &ret)
{
char c;
int sgn;
if(c=getchar(),c==EOF) return ;
while(c!='-'&&(c<''||c>'')) c=getchar();
sgn=(c=='-')?-:;
ret=(c=='-')?:(c-'');
while(c=getchar(),c>=''&&c<='') ret=ret*+(c-'');
ret*=sgn;
return ;
} const int maxn = 5e4+;
int lv[maxn<<],rv[maxn<<], setv[maxn<<]; //lv,rv数组可有可无,lsum rsum数组已经包含了他们的意义。
int lsum[maxn<<],rsum[maxn<<],sum[maxn<<]; void push_up(int l,int r,int pos)
{
lv[pos] = lv[pos<<];
rv[pos] = rv[pos<<|];
lsum[pos] = lsum[pos<<];
rsum[pos] = rsum[pos<<|];
sum[pos] = max(sum[pos<<],sum[pos<<|]);
sum[pos] = max(sum[pos],rsum[pos<<]+lsum[pos<<|]);
int mid = (l + r) >> ;
if (rv[pos<<] ==lv[pos<<|] && !rv[pos<<])
{
if (lsum[pos<<] == mid - l + )
lsum[pos] += lsum[pos<<|];
if (rsum[pos<<|] == r - mid)
rsum[pos] += rsum[pos<<];
sum[pos] = max(sum[pos],rsum[pos<<]+lsum[pos<<|]);
}
} void push_down(int l,int r,int pos)
{
if (~setv[pos])
{
int mid = (l + r) >> ;
setv[pos<<] = setv[pos<<|] = setv[pos];
lv[pos<<] = setv[pos];
lv[pos<<|] = setv[pos];
rv[pos<<] = setv[pos];
rv[pos<<|] = setv[pos];
lsum[pos<<] = (setv[pos] ? : (mid-l+));
rsum[pos<<] = (setv[pos] ? : (mid-l+));
lsum[pos<<|] = (setv[pos] ? : (r-mid));
rsum[pos<<|] = (setv[pos] ? : (r-mid));
sum[pos<<] = (setv[pos] ? : (mid-l+));
sum[pos<<|] = (setv[pos] ? : (r-mid));
setv[pos] = -;
}
} void build (int l,int r,int pos)
{
if (l == r)
{
rv[pos] = lv[pos] = ;
sum[pos] = lsum[pos] = rsum[pos] = ;
return;
}
int mid = (l + r) >> ;
build(l,mid,pos<<);
build(mid+,r,pos<<|);
push_up(l,r,pos);
} void update(int l,int r,int pos,int ua,int ub,int val)
{
if (ua <= l && ub >= r)
{
setv[pos] = val;
lv[pos] = val;
rv[pos] = val;
lsum[pos] = (val ? : (r-l+));
rsum[pos] = (val ? : (r-l+));
sum[pos] = (val ? : (r-l+));
return;
}
int mid = (l + r) >> ;
push_down(l,r,pos);
if (ua <= mid)
update(l,mid,pos<<,ua,ub,val);
if (ub > mid)
update(mid+,r,pos<<|,ua,ub,val);
push_up(l,r,pos);
} int query(int l,int r,int pos,int x)
{
if (lsum[pos] >= x)
{
return l; }
int mid = (l + r) >> ;
push_down(l,r,pos);
if (sum[pos<<] >= x)
return query(l,mid,pos<<,x);
/*else if (rsum[pos<<1]&&rsum[pos<<1] + lsum[pos<<1|1] >= x) //注释部分是错误的,,看起来很像但是不一样的
return query(l,mid,pos<<1,rsum[pos<<1]);*/
else if (rsum[pos<<] + lsum[pos<<|] >= x)
return mid+-rsum[pos<<];
else
return query(mid+,r,pos<<|,x);
} int main(void)
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int n,q;
while (~scanf ("%d%d",&n,&q))
{
build(,n,);
memset(setv,-,sizeof(setv));
for (int i = ; i < q; i++)
{
int op,x,y;
scanf ("%d",&op);
if (op == )
{
scanf ("%d",&x);
if (sum[] < x)
{
printf("0\n");
continue;
}
int p = query(,n,,x);
printf("%d\n",p);
update(,n,,p,p+x-,);
}
else
{
scanf ("%d%d",&x,&y);
update(,n,,x,y+x-,);
}
}
}
return ;
}
poj3667---Hotel 线段树区间合并,区间更新的更多相关文章
- 2015 UESTC 数据结构专题D题 秋实大哥与战争 变化版本的线段树,合并区间,单点查询
D - 秋实大哥与战争 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/59 D ...
- 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间合并(单点更新、区间查询)
P4513 小白逛公园 题目背景 小新经常陪小白去公园玩,也就是所谓的遛狗啦… 题目描述 在小新家附近有一条“公园路”,路的一边从南到北依次排着nn个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩 ...
- HDU 3577Fast Arrangement(线段树模板之区间增减更新 区间求和查询)
Fast Arrangement Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- POJ 3468 A Simple Problem with Integers(线段树模板之区间增减更新 区间求和查询)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 140120 ...
- codeforces Good bye 2016 E 线段树维护dp区间合并
codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...
- HDU 1754 I Hate It(线段树单点替换+区间最值)
I Hate It [题目链接]I Hate It [题目类型]线段树单点替换+区间最值 &题意: 本题目包含多组测试,请处理到文件结束. 在每个测试的第一行,有两个正整数 N 和 M ( 0 ...
- hdu1754(线段树单点替换&区间最值模板)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754 题意:中文题诶- 思路:线段树单点替换&区间最大值查询模板 代码: #include & ...
- HDU 3397 Sequence operation(区间合并 + 区间更新)
题目链接:pid=3397">http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意:给定n个数,由0,1构成.共同拥有5种操作. 每一个操 ...
- [USACO08FEB]酒店Hotel 线段树
[USACO08FEB]酒店Hotel 线段树 题面 其实就是区间多维护一个lmax,rmax(表示从左开始有连续lmax个空房,一直有连续rmax个空房到最右边),合并时讨论一下即可. void p ...
- Codeforces295A - Greg and Array(线段树的成段更新)
题目大意 给定一个序列a[1],a[2]--a[n] 接下来给出m种操作,每种操作是以下形式的: l r d 表示把区间[l,r]内的每一个数都加上一个值d 之后有k个操作,每个操作是以下形式的: x ...
随机推荐
- 形形色色的软件生命周期模型(4)——MSF、实用型
摘要: 读大学时,我们曾经学习过不少软件生命周期模型,当时还不是很懂软件开发,你可能会觉得这些东西很新奇.在实际工作中,你会发现这些模型其实很难应用,与此同时你会接触到RUP.MSF等权威软件公司的生 ...
- iOS中block实现的探究
[0. Brief introduction of block] Block是iOS4.0+ 和Mac OS X 10.6+ 引进的对C语言的扩展,用来实现匿名函数的特性. 用维基百科的话来说,Blo ...
- 现代的新语言--Swift初探
新的语言 WWDC简短的介绍,新的语言Swift就问世了,尽管新语言的名字导致贴吧下歌手粉丝和开发人员们争抢地盘- -,只是雨燕就是这么来了. WWDC keynote里给Swift打上了非常多标签: ...
- android 多项对话框
在main.xml中 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:a ...
- 打开SQL Server 配置管理器时出现了问题
解决方法: 1.找到sqlmgmproviderxpsp2up.mof的文件位置 2.打开window+R打开命令提示符(输入cmd):输入sqlmgmproviderxpsp2up.mof的文件位置 ...
- hdu 1076
水题 AC代码: #include <iostream> using namespace std; int main() { int i,k,t,y,n; cin>>t; wh ...
- 图片设置3D效果
/** * 图片绘制3d效果 * @param srcImage * @param radius * @param border * @param padding * @return * @throw ...
- HTML与CSS入门——第六章 使用字体
知识点: 1.粗体.斜体和特殊文本格式的使用 2.字体的调整方法 3.特殊字符的使用方法 6.1 粗体.斜体和特殊文本格式: font-weight控制粗细 加粗<strong> font ...
- 规约模式(Specification Pattern)
前期准备之规约模式(Specification Pattern) 一.前言 在专题二中已经应用DDD和SOA的思想简单构建了一个网上书店的网站,接下来的专题中将会对该网站补充更多的DDD的内容.本专题 ...
- iOS_SN_地图的使用(2)
上一篇讲的是地图的基本使用,和注意事项,这一篇主要讲POI检索.百度地图SDK提供三种类型的POI检索:周边检索.区域检索和城市内检索.下面将以周边检索为例,向大家介绍如何使用检索服务. - (voi ...