poj3667---Hotel 线段树区间合并,区间更新
题意:有N个房间,M次操作。有两种操作(1)"1 a",表示找到连续的长度为a的空房间,如果有多解,优先左边的,即表示入住。(2)"2 b len",把起点为b长度的len的房间清空,即退房。三个数组分别记录 lsum区间左值 rsum区间右值 sum区间最大值。
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const double eps = 1e-;
template <class T>
inline bool scan_d(T &ret)
{
char c;
int sgn;
if(c=getchar(),c==EOF) return ;
while(c!='-'&&(c<''||c>'')) c=getchar();
sgn=(c=='-')?-:;
ret=(c=='-')?:(c-'');
while(c=getchar(),c>=''&&c<='') ret=ret*+(c-'');
ret*=sgn;
return ;
} const int maxn = 5e4+;
int lv[maxn<<],rv[maxn<<], setv[maxn<<]; //lv,rv数组可有可无,lsum rsum数组已经包含了他们的意义。
int lsum[maxn<<],rsum[maxn<<],sum[maxn<<]; void push_up(int l,int r,int pos)
{
lv[pos] = lv[pos<<];
rv[pos] = rv[pos<<|];
lsum[pos] = lsum[pos<<];
rsum[pos] = rsum[pos<<|];
sum[pos] = max(sum[pos<<],sum[pos<<|]);
sum[pos] = max(sum[pos],rsum[pos<<]+lsum[pos<<|]);
int mid = (l + r) >> ;
if (rv[pos<<] ==lv[pos<<|] && !rv[pos<<])
{
if (lsum[pos<<] == mid - l + )
lsum[pos] += lsum[pos<<|];
if (rsum[pos<<|] == r - mid)
rsum[pos] += rsum[pos<<];
sum[pos] = max(sum[pos],rsum[pos<<]+lsum[pos<<|]);
}
} void push_down(int l,int r,int pos)
{
if (~setv[pos])
{
int mid = (l + r) >> ;
setv[pos<<] = setv[pos<<|] = setv[pos];
lv[pos<<] = setv[pos];
lv[pos<<|] = setv[pos];
rv[pos<<] = setv[pos];
rv[pos<<|] = setv[pos];
lsum[pos<<] = (setv[pos] ? : (mid-l+));
rsum[pos<<] = (setv[pos] ? : (mid-l+));
lsum[pos<<|] = (setv[pos] ? : (r-mid));
rsum[pos<<|] = (setv[pos] ? : (r-mid));
sum[pos<<] = (setv[pos] ? : (mid-l+));
sum[pos<<|] = (setv[pos] ? : (r-mid));
setv[pos] = -;
}
} void build (int l,int r,int pos)
{
if (l == r)
{
rv[pos] = lv[pos] = ;
sum[pos] = lsum[pos] = rsum[pos] = ;
return;
}
int mid = (l + r) >> ;
build(l,mid,pos<<);
build(mid+,r,pos<<|);
push_up(l,r,pos);
} void update(int l,int r,int pos,int ua,int ub,int val)
{
if (ua <= l && ub >= r)
{
setv[pos] = val;
lv[pos] = val;
rv[pos] = val;
lsum[pos] = (val ? : (r-l+));
rsum[pos] = (val ? : (r-l+));
sum[pos] = (val ? : (r-l+));
return;
}
int mid = (l + r) >> ;
push_down(l,r,pos);
if (ua <= mid)
update(l,mid,pos<<,ua,ub,val);
if (ub > mid)
update(mid+,r,pos<<|,ua,ub,val);
push_up(l,r,pos);
} int query(int l,int r,int pos,int x)
{
if (lsum[pos] >= x)
{
return l; }
int mid = (l + r) >> ;
push_down(l,r,pos);
if (sum[pos<<] >= x)
return query(l,mid,pos<<,x);
/*else if (rsum[pos<<1]&&rsum[pos<<1] + lsum[pos<<1|1] >= x) //注释部分是错误的,,看起来很像但是不一样的
return query(l,mid,pos<<1,rsum[pos<<1]);*/
else if (rsum[pos<<] + lsum[pos<<|] >= x)
return mid+-rsum[pos<<];
else
return query(mid+,r,pos<<|,x);
} int main(void)
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int n,q;
while (~scanf ("%d%d",&n,&q))
{
build(,n,);
memset(setv,-,sizeof(setv));
for (int i = ; i < q; i++)
{
int op,x,y;
scanf ("%d",&op);
if (op == )
{
scanf ("%d",&x);
if (sum[] < x)
{
printf("0\n");
continue;
}
int p = query(,n,,x);
printf("%d\n",p);
update(,n,,p,p+x-,);
}
else
{
scanf ("%d%d",&x,&y);
update(,n,,x,y+x-,);
}
}
}
return ;
}
poj3667---Hotel 线段树区间合并,区间更新的更多相关文章
- 2015 UESTC 数据结构专题D题  秋实大哥与战争 变化版本的线段树,合并区间,单点查询
		
D - 秋实大哥与战争 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/59 D ...
 - 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间合并(单点更新、区间查询)
		
P4513 小白逛公园 题目背景 小新经常陪小白去公园玩,也就是所谓的遛狗啦… 题目描述 在小新家附近有一条“公园路”,路的一边从南到北依次排着nn个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩 ...
 - HDU 3577Fast Arrangement(线段树模板之区间增减更新 区间求和查询)
		
Fast Arrangement Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
 - POJ 3468 A Simple Problem with Integers(线段树模板之区间增减更新 区间求和查询)
		
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 140120 ...
 - codeforces Good bye 2016 E 线段树维护dp区间合并
		
codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...
 - HDU 1754 I Hate It(线段树单点替换+区间最值)
		
I Hate It [题目链接]I Hate It [题目类型]线段树单点替换+区间最值 &题意: 本题目包含多组测试,请处理到文件结束. 在每个测试的第一行,有两个正整数 N 和 M ( 0 ...
 - hdu1754(线段树单点替换&区间最值模板)
		
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754 题意:中文题诶- 思路:线段树单点替换&区间最大值查询模板 代码: #include & ...
 - HDU 3397 Sequence operation(区间合并 + 区间更新)
		
题目链接:pid=3397">http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意:给定n个数,由0,1构成.共同拥有5种操作. 每一个操 ...
 - [USACO08FEB]酒店Hotel 线段树
		
[USACO08FEB]酒店Hotel 线段树 题面 其实就是区间多维护一个lmax,rmax(表示从左开始有连续lmax个空房,一直有连续rmax个空房到最右边),合并时讨论一下即可. void p ...
 - Codeforces295A - Greg and Array(线段树的成段更新)
		
题目大意 给定一个序列a[1],a[2]--a[n] 接下来给出m种操作,每种操作是以下形式的: l r d 表示把区间[l,r]内的每一个数都加上一个值d 之后有k个操作,每个操作是以下形式的: x ...
 
随机推荐
- java基础知识(二)
			
java的布局管理: borderLayout:则将板块分为东西南北中五个方向,每添加一个组件就要指定组件摆放的方位,放置在东西南北四个方向的组件将贴边放置.当拉大Frame的时候,处在center( ...
 - awr报告基本操作
			
1.查看当前的AWR保存策略.设置:快照间隔.保存时间. SQL> col SNAP_INTERVAL format a20 SQL> col RETENTION format a2 ...
 - JS(一)
			
循环还是很有意思的: 1) 安全数的作业: <!DOCTYPE html> <html lang="en"> <head> <meta c ...
 - Python进阶(面向对象编程基础)(一)
			
鉴于昨天被类和函数折腾得晕头转向,今特把类的知识翻出来温习. 1.定义类并创建实力对象 #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ ...
 - 设置UIScrollView只可以水平或者竖直滚动
			
UIScrollView里边包含多个UIWebView: 可以通过设置contentSize的值,设置其width为UIScrollerView可视区域的宽度:即UIScrollView的width, ...
 - Vim的设置和使用——编程者
			
一.第一个插件:Ctags 当我们看到一个陌生的变量或者函数,我们总想知道它的含义,因此,快速找到它的定义很重要.Ctags插件中的"Ctrl+]"快捷键就可以做到. 二.教你高效 ...
 - Jquery autocomplete 插件使用
			
轻松实现类似百度输入框联想功能: autocomplete 是一个很厉害的插件,该插件基于jquery,在jquery官网能下载到最新版本. 首先,jQuery UI 是基于 jQuery 的,所以, ...
 - Android 属性动画(一)
			
1.概述 Android提供了几种动画类型:View Animation .Drawable Animation .Property Animation .View Animation相当简单,不过只 ...
 - mybati之day02
			
今天开始讲解mybatis的第二天内容 一,拼接sql 在mapper.xml中,会多次使用到同一条sql片段,这时为了简便书写,将其定义出来 <sql id="base_sql&q ...
 - MVC,jquery异步
			
创建一个Ajax控制器 using System; using System.Collections.Generic; using System.Linq; using System.Web; usi ...