题意:有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 ...
随机推荐
-
【Android开发坑系列】之PopupWindow
PopupWindow在4.0之前的版本有个系统级别的BUG,必须借助一段自定义的fix代码来修复.其中mPopPm就是PopupWindow实例.java.lang.NullPointerExcep ...
-
JDBC 常用驱动类及url格式
1. oracle <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</ ...
-
Docker 选项和命令
选项 -D=true|false 使用 debug 模式.默认为 false. -H, --host=[unix:///var/run/docker.sock]: tcp://[host:port]来 ...
-
TIMAC 学习笔记(三)
本文主要内容参考 <Security on TI IEEE 802.15.4 Compliant RF Devices>.<Design Note DN108>.<IEE ...
-
C# XmlSerializer序列化浅析
C# 中使用 XmlSerializer 实现类和xml文件的序列化和反序列化,使用起来非常简单. C# XmlSerializer实现序列化: XmlSerializer xml = new Xml ...
-
Chrome开发者控制台操作教程
1清空控制台 在控制台下有个clear console的按钮,点击的时候会清空控制台. 清空控制台 2让Chrome中的页面可编辑 有的时候我们需要临时改变页面上的文字,图案等信息,一种常见的方法是 ...
-
谈谈ThreadLocal的设计及不足
用Java语言开发的同学对 ThreadLocal 应该都不会陌生,这个类的使用场景很多,特别是在一些框架中经常用到,比如数据库事务操作,还有MVC框架中数据跨层传递.这里我们简要探讨下 Thread ...
-
[原]Jenkins(十五)---jenkins插件之deploy
/** * lihaibo * 文章内容都是根据自己工作情况实践得出. *如有错误,请指正 * 版权声明:本博客欢迎转发,但请保留原作者信息! http://www.cnblogs.com/horiz ...
-
基于tensorflow的MNIST手写识别
这个例子,是学习tensorflow的人员通常会用到的,也是基本的学习曲线中的一环.我也是! 这个例子很简单,这里,就是简单的说下,不同的tensorflow版本,相关的接口函数,可能会有不一样哟.在 ...
-
linux下编译Zero C ICE
0.简介 ZeroC ICE 是指ZeroC公司(www.zeroc.com)的ICE(Internet Communications Engine)中间件平台. 目前ICE平台中包括Ice,Ice- ...