【POJ3667】Hotel(线段树)
题意:有n个依次编号的元素,要求维护以下两个操作:
1.询问整个数列中是否有长度>=x的连续的一段未被标记的元素,若无输出0,若有输出最小的开始编号ans并将[ans,ans+x-1]标记
2.将[x,x+y-1]其中的元素取消标记(如果有)
n,m<=5e4
思路:线段树区间合并
记录从左、右边开始最长连续长度,一段最长连续长度,以及标记状态
Pascal跑的比C++快……
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef vector<int> VI;
#define fi first
#define se second
#define MP make_pair
#define N 210000
#define M 7010
#define eps 1e-8
#define pi acos(-1)
#define oo 1e9
#define MOD 10007 struct node
{
int l,r,a,s;
}t[N]; void build(int l,int r,int p)
{
t[p].l=t[p].r=t[p].s=r-l+;
t[p].a=;
if(l==r) return;
int mid=(l+r)>>;
build(l,mid,p<<);
build(mid+,r,p<<|);
} void pushdown(int l,int r,int p)
{
int ls=p<<; int rs=ls+;
int mid=(l+r)>>;
if(t[p].a==)
{
t[ls].l=t[ls].r=t[ls].s=t[rs].l=t[rs].r=t[rs].s=;
t[ls].a=t[rs].a=;
}
if(t[p].a==)
{
t[ls].l=t[ls].r=t[ls].s=mid-l+;
t[rs].l=t[rs].r=t[rs].s=r-mid;
t[ls].a=t[rs].a=;
}
} void pushup(int l,int r,int p)
{
int ls=p<<; int rs=ls+;
if(t[ls].a==) t[p].l=t[ls].l+t[rs].l;
else t[p].l=t[ls].l;
if(t[rs].a==) t[p].r=t[rs].r+t[ls].r;
else t[p].r=t[rs].r;
t[p].s=max(max(t[ls].s,t[rs].s),t[ls].r+t[rs].l);
if(t[ls].a==&&t[rs].a==) t[p].a=;
else if(t[ls].a==&&t[rs].a==) t[p].a=;
else t[p].a=;
} int query(int l,int r,int x,int p)
{
if(l==r) return l;
pushdown(l,r,p);
int ls=p<<;
int rs=ls+;
int mid=(l+r)>>;
if(t[ls].s>=x) return query(l,mid,x,ls);
else if(t[ls].r+t[rs].l>=x) return mid-t[ls].r+;
else return query(mid+,r,x,rs);
} void update(int l,int r,int x,int y,int v,int p)
{
if(x<=l&&r<=y)
{
t[p].a=v;
if(v==)
{
t[p].l=t[p].r=t[p].s=;
}
if(v==)
{
t[p].l=t[p].r=t[p].s=r-l+;
}
return;
}
if(t[p].a==v) return;
pushdown(l,r,p);
int mid=(l+r)>>;
int ls=p<<;
int rs=ls+;
if(x<=mid) update(l,mid,x,y,v,ls);
if(y>mid) update(mid+,r,x,y,v,rs);
pushup(l,r,p);
} int main()
{ int n,m;
scanf("%d%d",&n,&m);
build(,n,);
for(int i=;i<=m;i++)
{
int x;
scanf("%d",&x);
if(x==)
{
int y;
scanf("%d",&y);
if(t[].s<y) printf("0\n");
else
{
int k=query(,n,y,);
printf("%d\n",k);
update(,n,k,k+y-,,);
}
}
else
{
int y,z;
scanf("%d%d",&y,&z);
update(,n,y,y+z-,,);
}
}
return ;
}
var t:array[..]of record
l,r,s:longint;
end;
tag:array[..]of longint;
n,m,i,x,y,z,k:longint; procedure build(l,r,p:longint);
var mid:longint;
begin
t[p].s:=r-l+;
tag[p]:=;
if l=r then exit; mid:=(l+r)>>;
build(l,mid,p<<);
build(mid+,r,p<<+);
end; function max(x,y:longint):longint;
begin
if x>y then exit(x);
exit(y);
end; procedure pushdown(l,r,p:longint);
var ls,rs,mid,len:longint;
begin
ls:=p<<; rs:=ls+;
mid:=(l+r)>>;
if tag[p]= then
begin
t[ls].l:=; t[ls].r:=; t[ls].s:=; tag[ls]:=;
t[rs].l:=; t[rs].r:=; t[rs].s:=; tag[rs]:=;
end;
if tag[p]= then
begin
len:=mid-l+;
t[ls].l:=len; t[ls].r:=len; t[ls].s:=len; tag[ls]:=;
len:=r-(mid+)+;
t[rs].l:=len; t[rs].r:=len; t[rs].s:=len; tag[rs]:=;
end;
end; procedure pushup(l,r,p:longint);
var ls,rs:longint;
begin
ls:=p<<; rs:=ls+;
if tag[ls]= then t[p].l:=t[ls].l+t[rs].l
else t[p].l:=t[ls].l;
if tag[rs]= then t[p].r:=t[rs].r+t[ls].r
else t[p].r:=t[rs].r;
t[p].s:=max(t[ls].s,t[rs].s);
t[p].s:=max(t[p].s,t[ls].r+t[rs].l);
if (tag[ls]=)and(tag[rs]=) then tag[p]:=
else if (tag[ls]=)and(tag[rs]=) then tag[p]:=
else tag[p]:=;
end; function query(l,r,v,p:longint):longint;
var mid,ls,rs:longint;
begin
if l=r then exit(l);
pushdown(l,r,p);
ls:=p<<; rs:=ls+;
mid:=(l+r)>>;
if t[ls].s>=v then query:=query(l,mid,v,p<<)
else if t[ls].r+t[rs].l>=v then query:=mid-t[ls].r+
else query:=query(mid+,r,v,p<<+);
end; procedure update(l,r,x,y,v,p:longint);
var mid,len:longint;
begin
if (l=x)and(r=y) then
begin
tag[p]:=v;
if v= then
begin
t[p].l:=; t[p].r:=; t[p].s:=;
end;
if v= then
begin
len:=y-x+;
t[p].l:=len; t[p].r:=len; t[p].s:=len;
end;
exit;
end;
if tag[p]=v then exit;
pushdown(l,r,p);
mid:=(l+r)>>;
if (x>=l)and(y<=mid) then update(l,mid,x,y,v,p<<)
else if (x>mid)and(y<=r) then update(mid+,r,x,y,v,p<<+)
else
begin
update(l,mid,x,mid,v,p<<);
update(mid+,r,mid+,y,v,p<<+);
end;
pushup(l,r,p);
end; begin readln(n,m);
build(,n,);
for i:= to m do
begin
read(x);
if x= then
begin
read(y);
if t[].s<y then writeln()
else
begin
k:=query(,n,y,);
writeln(k);
update(,n,k,k+y-,,);
end;
end;
if x= then
begin
read(y,z);
update(,n,y,y+z-,,);
end;
end; end.
【POJ3667】Hotel(线段树)的更多相关文章
- [USACO08FEB]酒店Hotel 线段树
[USACO08FEB]酒店Hotel 线段树 题面 其实就是区间多维护一个lmax,rmax(表示从左开始有连续lmax个空房,一直有连续rmax个空房到最右边),合并时讨论一下即可. void p ...
- 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 Hotel Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 94 ...
- PKU 3667 Hotel(线段树)
Hotel The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a ...
- Hotel(线段树合并)
Hotel Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 14958 Accepted: 6450 Descriptio ...
- 洛谷P2894 [USACO08FEB]酒店Hotel [线段树]
题目传送门 酒店 题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and ...
- poj3667【线段树】/【类似权值线段树写法】
题意:n个空房间.两种操作:1.选择最小的连续D个房间入住,并输出这连续D个房间的最小标号.2.将某个区间内的房间全部退房. #include <cstdio> #include < ...
- POJ 1823 Hotel 线段树
题目链接 线段树的区间合并. 和上一题差不多....第三种操作只需要输出maxx[1]的值就可以. #include <iostream> #include <vector> ...
- poj3667(线段树)
题目连接:http://poj.org/problem?id=3667 题意:1 a:询问是不是有连续长度为a的空房间,有的话住进最左边 2 a b:将[a,a+b-1]的房间清空 线段树操作:upd ...
- poj Hotel 线段树
经典线段树的题. 每个节点存储的信息:左端点连续空房间的长度,右端点连续空房间长度,连续空房间的最大长度. 由于要求每次必须从尽量靠左边的位置进行居住,那么搜索时应尽量让区间起始位置更小: 1.如果当 ...
随机推荐
- LOJ#6342. 跳一跳(期望)
题意 $n \leqslant 10^5$ Sol 随便推一推就好了吧.. $f[i] = \frac{f[i] + f[i +1] + \dots f[n]}{n - i + 1} + 1$ 移一下 ...
- JS - OOP-继承的最佳实现方式
如上图,使用第三种方式实现继承最好,也就是加了下划线的. 但是Object.create方法是ES6才支持的,所以,右边就写了一个实现其同样功能的函数.
- spring MVC体系结构和请求控制器
MVC处理过程 spring MVC架构模式都进行了分层设计如下 数据访问接口:DAO层 处理业务逻辑层:service层 数据实体:POJO 负责前端请求的接受并处理:servlet 负责前端页面展 ...
- 【PHP】根据两地经纬度计算距离
最近做一个H5活动的项目,有个要求是必须现场玩家才能参与,所以就需要计算玩家位置和活动地点的距离来判断是否在活动现场. 以下是写的一个根据经纬度计算两地距离的方法 1 function getDist ...
- python代码notepad++不变色问题。
原来是文档后缀名是.txt造成的,应该改成.py,疏忽了...
- 三次样条插值matlab实现
三次样条插值matlab实现 %三次样条差值-matlab通用程序 - zhangxiaolu2015的专栏 - CSDN博客 https://blog.csdn.net/zhangxiaolu201 ...
- 动态规划:HDU2844-Coins(多重背包的二进制优化)
Coins Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Subm ...
- Tomcat之web.xml中的<url-pattern>标签
关于web.xml配置中的<url-pattern> 标签<url-pattern> <url-pattern>是我们用Servlet做Web项目时需要经常配置的标 ...
- Spring Boot 开发系列一 开发环境的一些九九
从今天开始写这个Spring Boot 开发系列,我是第二周学习JAVA的,公司号称springboot把JAVA的开发提升到填空的能力,本人是NET转JAVA的,想看看这个填空的东西到底有多强.废话 ...
- SparkStreaming和Kafka的整合
当我们正确地部署好Spark Streaming,我们就可以使用Spark Streaming提供的零数据丢失机制.需要满足以下几个先决条件: 1.输入的数据来自可靠的数据源和可靠的接收器: 2.应用 ...