题意:有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. vue.js 一(基础环境搭建)

    之前由于看了React的东西,写了两篇React的脚手架搭建,一是给自己记一点可用的东西,免得每次都去找,毕竟搭建环境在项目相对固定的时期不是经常要干的事情,一段时间不用就会忘记了. 前端的js框架还 ...

  2. php五种常见的设计模式

    工厂模式 工厂模式是最常用的实例化对象的模式,是用工厂方法代替new操作的一种模式 使用工厂模式的好处是:如果想要更改实例化的类名,则只需要更改该工厂方法内容即可,不需逐一寻找代码中具体实例化的地方( ...

  3. ecshop里操作session与cookie

    目录 操作session 操作cookie html模板里提交保存用用户名 php里 js里保存cookie js里读取cookie html模板里smart的保留变量 html模板里取session ...

  4. <Docker学习>1. 简介

    Q: Dokcer是什么? A: 是一种虚拟化技术.参考https://www.imooc.com/learn/867快速了解Docker. Q: 传统虚拟机技术和Dokcer的区别? A: 传统虚拟 ...

  5. A1042 Shuffling Machine (20)

    1042 Shuffling Machine (20)(20 分) Shuffling is a procedure used to randomize a deck of playing cards ...

  6. java模式及其应用场景

    最经典的java 23种设计模式及具体例子(转发) 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容 ...

  7. Django基于Pycharm开发之三[命名空间 与过滤器]

    关于命名空间的问题,在project项目中,我们可以设置路由类似于: from django.conf.urls import url,includefrom django.contrib impor ...

  8. cglib动态代理之原理说明

    cglib采用了非常底层的字节码技术,通过目标类的字节码,为目标类创建子类,并在子类中用方法拦截技术,拦截所有父类方法的调用,并对拦截方法进行增强. 1)底层采用字节码框架ASM,来转换字节码来生成新 ...

  9. UNIX 系统中 wc 程序的主要部分

    以下代码为 UNIX 系统中 wc 程序的骨干部分 #include <stdio.h> #define IN 1 #define OUT 0 int main(int argc, cha ...

  10. MD5碰撞

    if ( $_POST['param1'] !==$_POST['param2'] && md5($_POST['param1']) === md5($_POST['param2']) ...