题目链接:http://poj.org/problem?id=3667

最初给你n间空房,m个操作:

  操作1 a 表示检查是否有连续的a间空房,输出最左边的空房编号,并入住a间房间。

  操作2 a b 表示将编号为a之后的b间房间清空。

典型的区间合并问题,这位大牛讲的更清楚:http://www.cnblogs.com/yewei/archive/2012/05/05/2484471.html

代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 5e4 + ;
//sum表示这个区间的最大数,lsum表示从这个区间最左边开始连续的最大数,rsum与lsum方向相反
struct data {
int l , r , lsum , rsum , sum , cover;
}T[MAXN << ]; void build(int p , int l , int r) {
int mid = (l + r) >> ;
T[p].lsum = T[p].rsum = T[p].sum = r - l + ;
T[p].cover = -;
T[p].l = l , T[p].r = r;
if(l == r)
return ;
build(p << , l , mid);
build((p << )| , mid + , r);
} void Pushdown(int p) {
if(T[p].cover != -) {
int ls = p << , rs = (p << )|;
T[ls].cover = T[rs].cover = T[p].cover;
T[ls].lsum = T[ls].rsum = T[ls].sum = T[p].cover ? : T[ls].r - T[ls].l + ;
T[rs].lsum = T[rs].rsum = T[rs].sum = T[p].cover ? : T[rs].r - T[rs].l + ;
T[p].cover = -;
}
} void Pushup(int p) {
T[p].lsum = T[p << ].lsum;
T[p].rsum = T[(p << )|].rsum;
if(T[p].lsum == T[p << ].r - T[p << ].l + )
T[p].lsum += T[(p << )|].lsum;
if(T[p].rsum == T[(p << )|].r - T[(p << )|].l + )
T[p].rsum += T[p << ].rsum;
int temp = max(T[(p << )|].sum , T[p << ].rsum + T[(p << )|].lsum);
T[p].sum = max(T[p << ].sum , temp);
} int query(int p , int len) {
int mid = (T[p].l + T[p].r) >> ;
if(T[p].l == T[p].r) {
return T[p].l;
}
Pushdown(p);
if(T[p << ].sum >= len) { //左孩子区间的最大数,优先选左孩子
return query(p << , len);
}
else if(T[p << ].rsum + T[(p << )|].lsum >= len) { //其次要是左孩子的rsum和右孩子的lsum 加起来大于len
return mid - T[p << ].rsum + ;
}
else {
return query((p << )| , len); //最后就是右孩子
}
} void updata(int p , int l , int r , int flag) {
int mid = (T[p].l + T[p].r) >> ;
if(T[p].l == l && T[p].r == r) {
T[p].sum = T[p].lsum = T[p].rsum = flag ? : r - l + ;
T[p].cover = flag;
return ;
}
Pushdown(p);
if(r <= mid) {
updata(p << , l , r , flag);
}
else if(l > mid) {
updata((p << )| , l , r , flag);
}
else {
updata(p << , l , mid , flag);
updata((p << )| , mid + , r , flag);
}
Pushup(p);
} int main()
{
int n , m , choose , u , v;
while(~scanf("%d %d" , &n , &m)) {
build( , , n);
while(m--) {
scanf("%d" , &choose);
if(choose == ) {
scanf("%d" , &u);
if(T[].sum < u)
printf("0\n");
else {
int pos = query( , u);
printf("%d\n" , pos);
updata( , pos , pos + u - , );
}
}
else {
scanf("%d %d" , &u , &v);
updata( , u , min(u + v - , n) , );
}
}
}
return ;
}

POJ 3667 Hotel (线段树区间合并)的更多相关文章

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

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

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

    两个题目都是用同一个模板,询问最长的连续未覆盖的区间 . lazy代表是否有人,msum代表区间内最大的连续长度,lsum是从左结点往右的连续长度,rsum是从右结点往左的连续长度. 区间合并很恶心啊 ...

  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 Time Limit: 3000MSMemory Limit: 65536K Total Submissions: 10858Accepted: 4691 Description The ...

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

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

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

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

  7. poj3667 Hotel (线段树 区间合并)

    poj3667 HotelTime Limit: 3000MS Memory Limit: 65536KTotal Submissions: 18925 Accepted: 8242Descripti ...

  8. 【bzoj1593】[Usaco2008 Feb]Hotel 旅馆 线段树区间合并

    题目描述 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大的旅馆一共有N (1 <= N & ...

  9. POJ 2482 Stars in Your Window (线段树区间合并+扫描线)

    这题开始一直被矩形框束缚了,想法一直都是枚举线,但是这样枚举都需要O(n^2)...但是看了别人的思路,感觉这题思想真心很好(PS:开头好浪漫的描述啊,可惜并没有什么用)  题意就是在平面上给你一些星 ...

随机推荐

  1. 真正解决ASP.NET每一个页面首次访问超级慢的问题 (转载)

    原文:http://www.afuhao.com/article_articleId-219.shtml 摘要:ASP.NET页面首次打开很慢,但别的页面如果没有访问过,去访问也会慢.你也许认为它是在 ...

  2. PHPnow 升级后 PHP不支持GD、MySQL

    来自http://tunps.com/php-unsupport-gd-and-mysql-after-upgrade-phpnow 最近磁盘格式化误操作后,最近两天都在忙于数据恢复,现在才恢复正常. ...

  3. WebView点击加载的页面中的按钮时不弹出新窗口以及在加载后执行javascript

    mWebView.setWebViewClient(new WebViewClient() { //点击网页中按钮时,在原页面打开 public boolean shouldOverrideUrlLo ...

  4. I.MX6 android 设置 默认 动态桌面

    /************************************************************************ * I.MX6 android 设置 默认 动态桌面 ...

  5. git - 搭建git仓库

    1. 更新git版本: http://codelife.me/blog/2013/06/25/upgrade-git-on-centos-6-4/ 2. 建立git仓库: git init --bar ...

  6. Java [Leetcode 204]Count Primes

    题目描述: Description: Count the number of prime numbers less than a non-negative number, n. 解题思路: Let's ...

  7. T-SQL备忘(1):表联接

    测试用例表如下: 1.取2个成员表中的交集(A∩B) T-SQL: select Member1.Name,Member1.Age from Member1 join Member2 on Membe ...

  8. 用defy来潜水最终还是挂了........

    defy526是6级,,不过好像这次我用来潜过去不足2米还是挂掉了... 国际通用的防水级别认证体系: IPX-0 没有防水保护 IPX-1 设备在正常操作状态下,可以提供相当于3-5毫米/分钟降雨的 ...

  9. Winfrom 开发系统导航菜单

    先上图看效果在说. 效果图如上,在Web中这个一点难度都没有,几行Css+JS就搞定了.但是在Winfrom中.本来就是半杯水的水准,想做这个个导航菜单,发现真难找,找了很多都不合胃口,只能自己写个了 ...

  10. Centos6.5下编译安装ACE6.0

    ACE在Linux下的编译安装步骤(CentOS6.5 64Bit) Linux平台安装(CentOS6.5 64bit) 1, 下载ACE软件包,上传至Linux服务器(假设目录为/opt/ace, ...