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

代码:

#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. python3学习笔记目录

    目录: Python基础(一),Day1 python基础(二),Day2 python函数和常用模块(一),Day3 python函数和常用模块(二),Day4 python函数和常用模块(三),D ...

  2. 浅谈一下缓存策略以及memcached 、redis区别

    缓存策略三要素:缓存命中率   缓存更新策略  最大缓存容量.衡量一个缓存方案的好坏标准是:缓存命中率.缓存命中率越高,缓存方法设计的越好. 三者之间的关系为:当缓存到达最大的缓存容量时,会触发缓存更 ...

  3. 在Hadoop平台跑python脚本

    1.开发IDE,我使用的是PyCharm. 2.运行原理       使用python写MapReduce的“诀窍”是利用Hadoop流的API,通过STDIN(标准输入).STDOUT(标准输出)在 ...

  4. 解决客户 IE 浏览器"兼容性视图"设置带来的问题

    最近在给客户开发一个 ASP.NET web 报表时,发现客户的 IE8 浏览器上,看网页总是怪怪的. 调查后发现,客户的 IE8 浏览器,统一被设置成"对本地网络使用兼容性视图" ...

  5. margin和padding对行内元素的影响

    这个是在面试的时候,面试官问我的一个小问题 自己没有考虑过inline元素设置margin和padding的问题 学习的过程记录下来 1)inline元素的高度是由元素的内容决定的(字体的大小和行高) ...

  6. sharepoint获取exchange邮箱报错:该帐户无权模拟所请求的用户

    现象: sharepoint获取exchange邮箱报错:该帐户无权模拟所请求的用户 处理办法: 1.Open the Exchange Management Shell 2.输入: New-Mana ...

  7. ogrinfo使用

    简介 orginfo是OGR模块中提供的一个重要工具,用于读取地图文件中记录,可以指定筛选条件(按字段.sql.矩形范围) 使用方式 命令行参数 Usage: ogrinfo [--help-gene ...

  8. Spark中的RDD操作简介

    map(func) 对数据集中的元素逐一处理,变为新的元素,但一个输入元素只能有一个输出元素 scala> pairData.collect() res6: Array[Int] = Array ...

  9. 根据包名字符串跳转Activity

    /** * 跳转到对应activity */ public void toActivity(Context context,String fullName) { if (className != nu ...

  10. Spring(十)Spring任务调度

    一.计划任务 需要定时执行一些计划(定时更新等),这样的计划称之为计划任务 Spring抽象封装了Java提供的Timer与TimerTask类 也可以使用拥有更多任务计划功能的Quartz 二.Ti ...