Description

The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a vacation on the sunny shores of Lake Superior. Bessie, ever the competent travel agent, has named the Bullmoose Hotel on famed Cumberland Street as their vacation residence. This immense hotel has N (1 ≤ N ≤ 50,000) rooms all located on the same side of an extremely long hallway (all the better to see the lake, of course).

The cows and other visitors arrive in groups of size Di (1 ≤ Di ≤ N) and approach the front desk to check in. Each group i requests a set of Di contiguous rooms from Canmuu, the moose staffing the counter. He assigns them some set of consecutive room numbers r..r+Di-1 if they are available or, if no contiguous set of rooms is available, politely suggests alternate lodging. Canmuu always chooses the value of r to be the smallest possible.

Visitors also depart the hotel from groups of contiguous rooms. Checkout i has the parameters Xi and Di which specify the vacating of rooms Xi ..Xi +Di-1 (1 ≤ Xi ≤ N-Di+1). Some (or all) of those rooms might be empty before the checkout.

Your job is to assist Canmuu by processing M (1 ≤ M < 50,000) checkin/checkout requests. The hotel is initially unoccupied.

                              --by POJ

http://poj.org/problem?id=3667



给定初始值全0的区间[1,n],支持两种操作:

1 w //查询整个区间最左端长度为w的连续0区间,输出其左端点,并把她全变成1,不存在,则输出0
2 l len //把以l为左端点长度为len的区间清零
 
考虑线段树维护区间:
max:区间最长连续0;
lmax:区间左起最长连续0;
rmax:区间右起最长连续0;
然后把1操作拆成先查询再在此基础上修改,这样修改可与2操作共用函数
查询时
优先递归左半区间,
左区间max非法,则查询左区间rmax+右区间lmax,
再非法,则递归右半区间,
再非法,则返回0,
修改则走线段树正常区间修改流程,打标记什么的;
注意如果查询失败,记得不能进行修改;
然后,如果查到了单点,记得特判一下;
一开始,我想当然的想为1操作定义一个函数,为2操作定义一个函数;
这样第一个函数一边查询一边修改
然而这样就需要打各种各样修改位置不同的标记——因为查询的递归与修改的递归流程很不相似
废了好久,
然后才知道可以这样定函数,
重构,然后清晰了许多;
代码能力不够啊;
代码如下:
 #include<cstdio>
using namespace std;
int n,m,L,R;
struct tree{
int lmax,rmax,max,lz;
}line[];
void builine(int ,int ,int );
void up(int ,int ,int );
void down(int ,int ,int );
int search(int ,int ,int ,int );
void change(int ,int ,int ,int );
int main()
{
int i,j,k,ans;
scanf("%d%d",&n,&m);
builine(,n,);
for(i=;i<=m;i++){
scanf("%d",&j);
if(j==){
scanf("%d",&k);
ans=search(,n,,k);
printf("%d\n",ans);
L=ans;R=L+k-;
if(L)
change(,n,,);
}
else{
scanf("%d%d",&L,&k);
R=L+k-;
change(,n,,);
}
}
}
void builine(int l,int r,int nu){
if(l==r){
line[nu].lmax=line[nu].rmax=line[nu].max=;
return ;
}
int mid=(l+r)>>;
builine(l,mid,nu<<);
builine(mid+,r,nu<<|);
line[nu].lmax=line[nu].rmax=line[nu].max=line[nu<<].max+line[nu<<|].max;
}
void up(int l,int r,int nu){
int mid=(l+r)>>;
if(line[nu<<].max>line[nu<<|].max)
line[nu].max=line[nu<<].max;
else
line[nu].max=line[nu<<|].max;
if(line[nu].max<line[nu<<].rmax+line[nu<<|].lmax)
line[nu].max=line[nu<<].rmax+line[nu<<|].lmax;
line[nu].lmax=line[nu<<].lmax==(mid-l+)?line[nu<<].lmax+line[nu<<|].lmax:line[nu<<].lmax;
line[nu].rmax=line[nu<<|].rmax==(r-mid)?line[nu<<|].rmax+line[nu<<].rmax:line[nu<<|].rmax;
}
void down(int l,int r,int nu){
int mid=(l+r)>>;
if(line[nu].lz){
line[nu<<].lmax=line[nu<<].max=line[nu<<].rmax=((line[nu].lz-)^)*(mid-l+);
line[nu<<|].lmax=line[nu<<|].max=line[nu<<|].rmax=((line[nu].lz-)^)*(r-mid);
line[nu<<].lz=line[nu<<|].lz=line[nu].lz;
line[nu].lz=;
}
}
int search(int l,int r,int nu,int len){
int mid=(l+r)>>,ans;
down(l,r,nu);
if(l==r)
return line[nu].max*l;
if(line[nu<<].max>=len){
ans=search(l,mid,nu<<,len);
return ans;
}
if(line[nu<<].rmax+line[nu<<|].lmax>=len){
ans=mid-line[nu<<].rmax+;
return ans;
}
if(line[nu<<|].max>=len){
ans=search(mid+,r,nu<<|,len);
return ans;
}
return ;
}
void change(int l,int r,int nu,int x){
if(L<=l&&r<=R){
line[nu].lmax=line[nu].rmax=line[nu].max=(r-l+)*(x^);
line[nu].lz=x+;
return ;
}
down(l,r,nu);
int mid=(l+r)>>;
if(L<=mid)
change(l,mid,nu<<,x);
if(R>mid)
change(mid+,r,nu<<|,x);
up(l,r,nu);
}

祝AC

POJ P3667 Hotel——solution的更多相关文章

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

    题目传送门 /* 题意:输入 1 a:询问是不是有连续长度为a的空房间,有的话住进最左边 输入 2 a b:将[a,a+b-1]的房间清空 线段树(区间合并):lsum[]统计从左端点起最长连续空房间 ...

  2. POJ 3667 Hotel(线段树)

    POJ 3667 Hotel 题目链接 题意:有n个房间,如今有两个操作 1.找到连续长度a的空房间.入住,要尽量靠左边,假设有输出最左边的房间标号,假设没有输出0 2.清空[a, a + b - 1 ...

  3. poj 3667 Hotel (线段树)

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

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

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

  5. poj 3667 Hotel(线段树,区间合并)

    Hotel Time Limit: 3000MSMemory Limit: 65536K Total Submissions: 10858Accepted: 4691 Description The ...

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

    题目链接:http://poj.org/problem?id=3667 最初给你n间空房,m个操作: 操作1 a 表示检查是否有连续的a间空房,输出最左边的空房编号,并入住a间房间. 操作2 a b ...

  7. (简单) POJ 3667 Hotel,线段树+区间合并。

    Description The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and e ...

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

    http://poj.org/problem?id=3667 题意: 有N个房间,M次操作.有两种操作(1)"1a",表示找到连续的长度为a的空房间,如果有多解,优先左边的,即表示 ...

  9. Poj 3667——hotel——————【线段树区间合并】

    Hotel Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 13124   Accepted: 5664 Descriptio ...

随机推荐

  1. 总结day6 ---- set集合,基本类型的相互转化,编码,数据类型总结,循环时候不要动列表或者字典,深浅copy

    python小数据池,代码块的最详细.深入剖析   一. id is == 二. 代码块 三. 小数据池 四. 总结 一,id,is,== 在Python中,id是什么?id是内存地址,比如你利用id ...

  2. php 内存分配新

    https://yq.aliyun.com/articles/38307 https://yq.aliyun.com/ziliao/132720 http://blog.liyiwei.cn/%E3% ...

  3. JS设计模式之单体模式(Singleton)

    单体模式作为一种软件开发模式在众多面向对象语言中得到了广泛的使用,在javascript中,单体模式也是使用非常广泛的,但是由于javascript语言拥有其独特的面向对象方式,导致其和一些传统面向对 ...

  4. day1: python3.5学习

    1. 基础知识 变量:用于存储信息,方便后面的调用 常量:python中是没有常量这一概念的,若想定义一个常量,需要将变量名大写 举例:name = "Helen"   #定义一个 ...

  5. ubuntu14 安装tftp服务器

    安装 sudo apt-get install tftp-hpa tftpd-hpa 配置 sudo gedit /etc/default/tftpd-hpa 打开tftpd-hpa修改里面的配置: ...

  6. BZOJ AC 300祭!

  7. 让字体在div容器中垂直居中

    1. 只显示一行数据的话: 给容器设置height和line-height,并使两个值相等,再加上over-flow:hidden .test{ height:40px; line-height:40 ...

  8. Spring AMQP

    Spring AMQP 是基于 Spring 框架的AMQP消息解决方案,提供模板化的发送和接收消息的抽象层,提供基于消息驱动的 POJO的消息监听等,很大方便我们使用RabbitMQ程序的相关开发. ...

  9. getSqlMapClientTemplate().insert()方法的返回值问题

    insert方法的返回值     今天碰到一个问题,就是关于ibatis的insert方法的返回值的问题.在网上找了很多例子,自己也亲自试了一下. 最后得出结论:insert方法返回的是在表中插入记录 ...

  10. 图像RGB2YUV与YUV2RGB格式互转介绍

    1 YUV格式与RGB格式说明 由于不同国家的电视信号系统支持的图像格式不同,有YUV格式成像,也有RGB格式成像,因此为了保证兼容性,需要进行RGB与YUV格式的互转. 另外YUV格式具有亮度信息和 ...