非常细腻的线段树题目啊,后来还是有个细节写错了,查了一个晚上。。就不分析了。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <utility>
#include <cstdlib>
using namespace std;
#define N 80011 struct node
{
int ls,rs,ms;
int pos;
int mark; // 0: unsure 1: all-empty 2: all-full
}tree[*N]; int n,m; void build(int l,int r,int rt)
{
tree[rt].ls = tree[rt].rs = tree[rt].ms = r-l+;
tree[rt].pos = l;
if(l == r)
{
return;
}
int mid = (l+r)/;
build(l,mid,*rt);
build(mid+,r,*rt+);
} int if_all_empty(int l,int r,int rt)
{
if(tree[rt].ls == r-l+)
return ;
return ;
} void update(int l,int r,int rt)
{
if(!tree[rt].mark)
return;
if(tree[rt].mark == ) //全空,则下传给左右子树
{
int len = r-l+;
tree[*rt].ls = tree[*rt].rs = tree[*rt].ms = (len+)/;
tree[*rt].pos = l;
tree[*rt+].ls = tree[*rt+].rs = tree[*rt+].ms = len/;
tree[*rt+].pos = (l+r)/+;
tree[*rt].mark = tree[*rt+].mark = ;
}
else if(tree[rt].mark == ) //全满,则下传给左右子树
{
tree[*rt].ls = tree[*rt].rs = tree[*rt].ms = ;
tree[*rt].pos = l;
tree[*rt+].ls = tree[*rt+].rs = tree[*rt+].ms = ;
tree[*rt+].pos = (l+r)/+;
tree[*rt].mark = tree[*rt+].mark = ;
}
tree[rt].mark = ; // not "== 0"
} int query(int l,int r,int dis,int rt)
{
update(l,r,rt);
if(tree[rt].ms<dis)
return ;
if(tree[rt].ms == dis)
return tree[rt].pos;
int mid = (l+r)/;
if(tree[*rt].ms>=dis)
return query(l,mid,dis,*rt);
if(tree[*rt].rs + tree[*rt+].ls>=dis)
return mid - tree[*rt].rs + ;
return query(mid+,r,dis,*rt+);
} void in_out(int l,int r,int aa,int bb,int flag,int rt) //flag == 1: insert else quit
{
if(aa>r||bb<l)
return;
if(aa<=l&&bb>=r)
{
if(flag == ) //如果当前要入住
{
tree[rt].ls = tree[rt].rs = tree[rt].ms = ;
tree[rt].pos = l;
tree[rt].mark = ;
}
else //如果当前要退房
{
tree[rt].ls = tree[rt].rs = tree[rt].ms = r-l+;
tree[rt].pos = l;
tree[rt].mark = ;
}
return;
}
update(l,r,rt);
int mid = (l+r)/;
in_out(l,mid,aa,bb,flag,*rt);
in_out(mid+,r,aa,bb,flag,*rt+); tree[rt].ls = tree[*rt].ls;
if(if_all_empty(l,mid,*rt))
tree[rt].ls += tree[*rt+].ls;
tree[rt].rs = tree[*rt+].rs;
if(if_all_empty(mid+,r,*rt+))
tree[rt].rs += tree[*rt].rs; tree[rt].ms = max(tree[*rt].rs+tree[*rt+].ls,max(tree[*rt].ms,tree[*rt+].ms)); if(tree[rt].ms == tree[*rt].ms) //如果当前区间最大空房数等于左子树最大空房数
tree[rt].pos = tree[*rt].pos; //则起点置为左子树的起点 else if(tree[rt].ms == tree[*rt].rs + tree[*rt+].ls) //同理
tree[rt].pos = mid - tree[*rt].rs + ; else
tree[rt].pos = tree[*rt+].pos;
} int main()
{
scanf("%d%d",&n,&m);
memset(tree,,sizeof(tree));
build(,n,);
int i,flag;
int x,dis;
for(i=;i<m;i++)
{
scanf("%d",&flag);
if(flag == )
{
scanf("%d",&dis);
int ans = query(,n,dis,);
printf("%d\n",ans);
if(ans)
in_out(,n,ans,ans+dis-,,);
}
else if(flag == )
{
scanf("%d%d",&x,&dis);
in_out(,n,x,x+dis-,,);
}
}
return ;
}

UESTC 1227 & POJ 3667 Hotel的更多相关文章

  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 (线段树区间合并)

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

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

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

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

    题目链接:http://poj.org/problem?id=3667 题目大意:一共有n个房间,初始时都是空的,现在有m个操作,操作有以下两种: 1.1 d :询问是否有连续d个空的房间,若有则输出 ...

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

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

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

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

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

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

随机推荐

  1. 非线性数据拟合-nls

    code{white-space: pre;} pre:not([class]) { background-color: white; }if (window.hljs && docu ...

  2. 【GPU编解码】GPU硬编码

    一.OpenCV中的硬编码 OpenCV2.4.6中,已实现利用GPU进行写视频,编码过程由cv::gpu::VideoWriter_GPU完成,其示例程序如下. int main(int argc, ...

  3. SFTP和FTS协议的区别

    都是为FTP连接加密,协议非常相似.一个是借助SSL协议加密,一个时借助SSH协议加密.SSL是为HTTP/SMTP等加密设计的:SSH是为TELNET/FTP等加密.建立传输通道而设计的.其实SSH ...

  4. Webform(内置对象-Response与Redirect、QueryString传值、Repeater删改)

    一.内置对象(一)Response - 响应请求对象1.定义:Response对象用于动态响应客户端请示,控制发送给用户的信息,并将动态生成响应.Response对象只提供了一个数据集合cookie, ...

  5. 转:【前端福利】用grunt搭建自动化的web前端开发环境-完整教程

    原文地址:http://blog.csdn.net/wangfupeng1988/article/details/46418203 jQuery在使用grunt,bootstrap在使用grunt,百 ...

  6. iOS 视频播放 - YVideoPlayer - UIView

    这是一个使用简便的视频播放框架,它基于UIView,它可以是一个小窗口,也可以是一个全屏的窗口 简单的方式加载Video框架: 一行代码加载! 一行代码更新! 下载链接 : https://githu ...

  7. IOS数组NSArray与NSMutableArray知识点

    此文是对数组NSArray与NSMutableArray知识点的总结,主要是一些常见的操作,别外一些操作见其相应的文档,下面的代码部分还运用的第三方插件BlocksKit相结合: a:Foundati ...

  8. JAVA基础学习day15--集合二 TreeSet和泛型

    一.TreeSet 1.1.TreeSet Set:hashSet:数据结构是哈希表.线程是非同步的.        保证元素唯一性的原理:判断元素的HashCode值是否相同.         如果 ...

  9. 多线程基础 (八)NSOperation相关

    额外的参考学习可以学习:http://www.cnblogs.com/YouXianMing/p/3707403.html 1.NSOperation简介   NSOperation的作用 配合使用N ...

  10. This is usually caused by using Struts tags without the associated filter. Struts tags are only usable when the request has p

    2014-09-16 15:47:51.590:WARN:oejs.ErrorPageErrorHandler:EXCEPTION org.apache.jasper.JasperException: ...