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

题意:

有N个房间,M次操作。有两种操作(1)"1a",表示找到连续的长度为a的空房间,如果有多解,优先左边的,即表示入住。(2)"2 b len",把起点为b长度的len的房间清空,即退房。

思路:

区间合并的线段树题。

其实如果单点更新和区间更新做得多了的话,区间合并也就不难了。

对于这道题,我们用线段树维护三个值,从左端开始的连续空房间数,从右边开始的连续空房间数,以及整个区间内最大的连续空房间数。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn=+; int n, m; struct node //维护从左端开始的最大连续空房间,从右端开始的最大连续空房间,总的最大连续空房间
{
int l,r;
int ls,rs,sum;
}t[maxn<<]; int lazy[maxn<<]; void PushUp(int o)
{
t[o].ls=t[o<<].ls;
t[o].rs=t[o<<|].rs;
int mid=(t[o].l+t[o].r)>>;
if(t[o].ls==mid-t[o].l+) t[o].ls+=t[o<<|].ls; //如果左半部分都是空房间,那么可以与右半部分的左边空房间连起来
if(t[o].rs==t[o].r-mid) t[o].rs+=t[o<<].rs;
t[o].sum=max(max(t[o<<].sum,t[o<<|].sum),t[o<<].rs+t[o<<|].ls);
} void PushDonw(int o)
{
if(lazy[o]!=-)
{
lazy[o<<]=lazy[o<<|]=lazy[o];
if(lazy[o]) //为1的话要将该区间置满
{
t[o<<].ls=t[o<<].rs=t[o<<].sum=;
t[o<<|].ls=t[o<<|].rs=t[o<<|].sum=;
}
else //为0的话要将该区间置空
{
t[o<<].ls=t[o<<].rs=t[o<<].sum=t[o<<].r-t[o<<].l+;
t[o<<|].ls=t[o<<|].rs=t[o<<|].sum=t[o<<|].r-t[o<<|].l+;
}
lazy[o]=-;
}
} void build(int l, int r, int o)
{
lazy[o]=-;
t[o].l=l;
t[o].r=r;
t[o].ls=t[o].rs=t[o].sum=r-l+;
if(l==r) return;
int mid=(l+r)>>;
build(l,mid,o<<);
build(mid+,r,o<<|);
} void update(int ql, int qr, int l, int r, int flag, int o)
{
if(ql<=l && qr>=r)
{
if(flag) t[o].ls=t[o].rs=t[o].sum=;
else t[o].ls=t[o].rs=t[o].sum=r-l+;
lazy[o]=flag;
return;
}
PushDonw(o);
int mid=(l+r)>>;
if(ql<=mid) update(ql,qr,l,mid,flag,o<<);
if(qr>mid) update(ql,qr,mid+,r,flag,o<<|);
PushUp(o);
} int query(int l, int r, int num, int o)
{
if(l==r) return l;
PushDonw(o);
int mid=(l+r)>>;
if(t[o<<].sum>=num) return query(l,mid,num,o<<);
else if(t[o<<].rs+t[o<<|].ls>=num) return mid-t[o<<].rs+;
else return query(mid+,r,num,o<<|);
} int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&m);
build(,n,);
while(m--)
{
int op;
scanf("%d",&op);
if(op==)
{
int x;
scanf("%d",&x);
if(t[].sum<x) {puts("");continue;}
int pos=query(,n,x,);
printf("%d\n",pos);
update(pos,pos+x-,,n,,);
}
else
{
int s,t;
scanf("%d%d",&s,&t);
update(s,s+t-,,n,,);
}
}
return ;
}

最新文章

  1. 将android模拟器上的db文件拷贝到电脑上
  2. Omu.AwesomeMvc.dll 和Omu.ValueInjecter.dll 介绍
  3. 如何修改ECShop发货单查询显示个数
  4. JS中的apply,call,bind深入理解
  5. 一个适用于层级目录结构的makefile模版
  6. 【风马一族_Android】Android 前端内容1
  7. win2008 r2 远程桌面问题
  8. ZOJ-2112-Dynamic Rankings(线段树套splay树)
  9. struts jsp传值到action,乱码的解决方案
  10. [Machine Learning]学习笔记-Logistic Regression
  11. Android热修复(动态加载)方案汇总
  12. docker 标记和推送镜像
  13. 我的第一篇博客。(JavaScript的声明和数据类型的一些笔记)
  14. bootstrap table dataView展开行详情,p元素自动换行
  15. Chapter5_初始化与清理_数组初始化与可变参数列表
  16. Python档案袋(变量与流程控制)
  17. Person Re-ID行人重试别数据集
  18. centos6.5/centos7安装部署企业内部知识管理社区系统wecenter
  19. 【面试题】Python高级开发工程师面试题
  20. C#.NET常见问题(FAQ)-找不到类型或命名空间名称“ManagementBaseObject”怎么办

热门文章

  1. 20170809直接访问功能测试Postman
  2. [LeetCode] 589. N-ary Tree Preorder Traversal_Easy
  3. [LeetCode] 102. Binary Tree Level Order Traversal_Medium tag: BFS
  4. Tesseract-OCR 训练过程 V3.02
  5. webpack 3 &amp; React 的配置 。
  6. zw版【转发&#183;台湾nvp系列Delphi例程】HALCON SmallestRectangle2
  7. Object-C-NSArray
  8. uva10167
  9. 数据仓库基础(九)Informatica小技巧(1)
  10. 20165207 Exp3 免杀原理与实践