题意:有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. Finders Keepers-freecodecamp算法题目

    Finders Keepers 1.要求 写一个 function,它遍历数组 arr,并返回数组中第一个满足 func 返回值的元素. 举个例子,如果 arr 为 [1, 2, 3],func 为 ...

  2. POI Excel 插入新的行,下面的行动态移动

    在做Excel 模板时,会有遇到  模板行数不固定,如下图  需要在行次4下面再插入一行:注意:(插入的行如果是下面空白行,需要创建行) 解决方法是使用shifRows方法,第1个参数是指要开始插入的 ...

  3. Mysql占用内存过高的优化过程

    一.环境说明: 操作系统:CentOS 6.5 x86_64 数据库:Mysql 5.6.22 服务器:阿里云VPS,32G Mem,0 swap 二.问题情况: 1.某日发现公司线上系统的Mysql ...

  4. IDEA整合Mybatis+Struts2+Spring (二)--整合框架

    二.搭建目录结构 我这里列出的是搭建完了之后所有的目录和文件,诸位先把目录文件建起来,然后我在给出文件内容 这里的目录建好之后还需要设置一下,让idea识别目录作用,选择File-Project St ...

  5. Python_深浅拷贝

    深浅拷贝 ‘copy’和'='的区别:copy会开辟一个新的空间,而‘=’不会. 浅copy只会copy第一层,再里边的就进行共享了. 需要记住的是copy之后记住的是内存寻址地址,而浅copy时如果 ...

  6. Mysql数据库的权限、索引基本操作

    数据库的关闭方法: .优雅的关闭数据库的方法: mysqladmin -uroot -p123456 shutdown .脚本关闭: /etc/init.d/mysqld stop .使用kill信号 ...

  7. win7旗舰版64位java的jdk环境变量的配置(2012-12-26-bd 写的日志迁移

    首先到oracle的官方网站http://www.oracle.com/technetwork/cn/java/javase/downloads/index.html下个JDK比如下图: 必须是win ...

  8. 栈及其DFS:B - Parentheses Balance

    解题心得及总结: 总结: 1.递推:又1推出n,数列中的基本到通项,最终目标得出通项公式. 递归:又n先压缩栈到1,再从函数的出口找到1,又1到n,再从n计算到1: 2.判断是否可以由递推或递推得出, ...

  9. P3386 【模板】二分图匹配(匈牙利&最大流)

    P3386 [模板]二分图匹配 题目背景 二分图 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式: 第一行,n,m,e 第二至e+1行,每行两个正 ...

  10. easyui的tree基本属性

    1.cascadeCheck,级联 默认情况下,是true,级联的,就是选中一个子节点,父节点是半选中状态,子节点全选中之后,父节点就是选中状态.