题意:有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(线段树)的更多相关文章

  1. [USACO08FEB]酒店Hotel 线段树

    [USACO08FEB]酒店Hotel 线段树 题面 其实就是区间多维护一个lmax,rmax(表示从左开始有连续lmax个空房,一直有连续rmax个空房到最右边),合并时讨论一下即可. void p ...

  2. POJ 3667 Hotel(线段树 区间合并)

    Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...

  3. poj 3667 Hotel (线段树)

    http://poj.org/problem?id=3667 Hotel Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 94 ...

  4. PKU 3667 Hotel(线段树)

    Hotel The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a ...

  5. Hotel(线段树合并)

    Hotel Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 14958   Accepted: 6450 Descriptio ...

  6. 洛谷P2894 [USACO08FEB]酒店Hotel [线段树]

    题目传送门 酒店 题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and ...

  7. poj3667【线段树】/【类似权值线段树写法】

    题意:n个空房间.两种操作:1.选择最小的连续D个房间入住,并输出这连续D个房间的最小标号.2.将某个区间内的房间全部退房. #include <cstdio> #include < ...

  8. POJ 1823 Hotel 线段树

    题目链接 线段树的区间合并. 和上一题差不多....第三种操作只需要输出maxx[1]的值就可以. #include <iostream> #include <vector> ...

  9. poj3667(线段树)

    题目连接:http://poj.org/problem?id=3667 题意:1 a:询问是不是有连续长度为a的空房间,有的话住进最左边 2 a b:将[a,a+b-1]的房间清空 线段树操作:upd ...

  10. poj Hotel 线段树

    经典线段树的题. 每个节点存储的信息:左端点连续空房间的长度,右端点连续空房间长度,连续空房间的最大长度. 由于要求每次必须从尽量靠左边的位置进行居住,那么搜索时应尽量让区间起始位置更小: 1.如果当 ...

随机推荐

  1. Android_组件_Activity基础

    一.概述 Activity是应用组件,提供了用户交互的窗口.一个应用由多个彼此联系的Activity组成.它大多数情况是全屏窗口显示,也可以作为悬浮窗口 或者 多窗口模式. 二.生命周期 下图是来自A ...

  2. ZendFramework-2.4 源代码 - 开始

    ZendFramework 是一种PHP框架. 写在前面 最早遇到ZendFramework是在阅读一款叫Magento电子商务系统源代码时看到,后来因为工作,把注意力侧重在其他方面,就搁置了继续了解 ...

  3. Flask学习笔记:数据库ORM操作MySQL+pymysql/mysql-python+SQLAlchemy/Flask-SQLAlchemy

    Python中使用sqlalchemy插件可以实现ORM(Object Relationship Mapping,模型关系映射)框架,而Flask中的flask-sqlalchemy其实就是在sqla ...

  4. Django配置邮箱登录

    1.settings下配置 # AUTH 方法(支持邮箱登录) AUTHENTICATION_BACKENDS = ('users.views.CustomBackend',) 2.views下逻辑如 ...

  5. Assignment HDU - 2853(二分图匹配 KM 新边旧边)

    传送门: Assignment HDU - 2853 题意:题意直接那松神的题意了.给了你n个公司和m个任务,然后给你了每个公司处理每个任务的效率.然后他已经给你了每个公司的分配方案,让你求出最多能增 ...

  6. The Moving Points - HDU - 4717 (模拟退火)

    题意 二维空间中有\(n\)个运动的点,每个点有一个初始坐标和速度向量.求出一个时间\(T\),使得此时任意两点之间的最大距离最小.输出\(T\)和最大距离. 题解 模拟退火. 这个题告诉了我,初始步 ...

  7. GIt-重置

    master分支在版本库的引用目录(.git/refs)中体现为一个引用文件.git/refs/heads/master,其内容就是分支中最新提交的提交ID. $ cat .git/refs/head ...

  8. #2 create and populate a database && realistic and practical applications (PART 2)

    Extends from the last chapter , This chapter takes a look at some real-world problems that can occur ...

  9. MVC中Spring.net 对基类控制器无效 过滤器控制器无效

    比如现在我又一个BaseController作为基类控制器,用于过滤权限.登录判断等作用,其它控制由原本的继承Controller,改为继承BaseController.然后BaseControlle ...

  10. 第2章c++简单程序设计

    第2章c++简单程序设计 知识梳理 以下是我遗忘以及认为重要的知识整理: 1.标识符的构成规则: 以大写字母.小写字母或下划线 _ 开始 由大写字母.小写字母.下划线 _ 或数字(0~9)组成 大写字 ...