旅馆

【问题描述】

OIEROIEROIER 们最近的旅游计划,是到长春净月潭,享受那里的湖光山色,以及明

媚的阳光。你作为整个旅游的策划者和负责人,选择在潭边的一家著名的旅馆住

宿。这个巨大的旅馆一共有 NNN (111 &lt;=&lt;=<= NNN &lt;=&lt;=<= 500005000050000)间客房,它们在同一层楼中顺次

一字排开,在任何一个房间里,只需要拉开窗帘,就能见到波光粼粼的潭面。

所有的旅游者,都是一批批地来到旅馆的服务台,希望能订到 DiDiDi (111 &lt;=&lt;=<= DiDiDi &lt;=&lt;=<= NNN)间连续的房间。服务台的接待工作也很简单:如果存在 rrr 满足编号为 rrr…rrr+DiDiDi-111

的房间均空着,他就将这一批顾客安排到这些房间入住;如果没有满足条件的 rrr,

他会道歉说没有足够的空房间,请顾客们另找一家宾馆。如果有多个满足条件的

rrr,服务员会选择其中最小的一个。

旅馆中的退房服务也是批量进行的。每一个退房请求由 222 个数字 XiXiXi、DiDiDi 描

述,表示编号为 XiXiXi…XiXiXi+DiDiDi-111 (111 &lt;=&lt;=<= XiXiXi &lt;=&lt;=<= NNN-DiDiDi+111)房间中的客人全部离开。退房前,

请求退掉的房间中的一些,甚至是所有,可能本来就无人入住。

你的工作,就是写一个程序,帮服务员为旅客安排房间。你的程序一共需要

处理 MMM (111 &lt;=&lt;=<= MMM &lt;=&lt;=<= 500005000050000)个按输入次序到来的住店或退房的请求。第一个请求到

来前,旅店中所有房间都是空闲的。

【输入格式】

从文件 hotel.inhotel.inhotel.in 中输入数据。

第 111 行: 222 个用空格隔开的整数:NNN、MMM

第 222…M+1M+1M+1 行: 第 i+1i+1i+1 描述了第 iii 个请求,如果它是一个订房请求,则用 222 个

数字 111、DiDiDi 描述,数字间用空格隔开;如果它是一个退房请求,用 333 个以空格隔

开的数字 222、XiXiXi、DiDiDi 描述。

【输出格式】

输出到文件 hotel.outhotel.outhotel.out 中。

第 111…??????行: 对于每个订房请求,输出 111 个独占 111 行的数字:如果请求能被

满足,输出满足条件的最小的 rrr;如果请求无法被满足,输出 000。

【样例输入】

101010 666

111 333

111 333

111 333

111 333

222 555 555

111 666

【样例输出】

111

444

777

000

555

【数据规模与约定】

对于 202020%的数据, 111<=NNN<=100100100,111<=MMM<=200200200

对于 100100100%的数据,111 <= NNN <= 500005000050000 ,111 <= MMM <= 500005000050000,

数据有梯度。

该题考试的时候打了并且重构一颗线段树,顺利跑过,下面让我们来分析一下:

线段树维护区间最长连续111,区间前缀最长连续111,后缀最长连续111

在查询的时候看这个区间的最长长度是否>=ddd

如果>=ddd,则先看左子树是否>=ddd,若否看跨区间的是否>=ddd,若否再找右子树

再支持一下区间赋值即可。

下面贴上我丑陋的代码:

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<ctime>
using namespace std;
#define N 50005
#include<iostream>
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (T[p].l+T[p].r>>1)
inline long long read(){
	long long ans=0,w=1;
	char ch=getchar();
	while(!isdigit(ch)){
		if(ch=='-')w=-1;
		ch=getchar();
	}
	while(isdigit(ch)){
		ans=(ans<<3)+(ans<<1)+ch-'0';
		ch=getchar();
	}
	return ans*w;
}
inline void write(long long x){
	if(x<0){
		x=-x;
		putchar('-');
	}
	if(x>9)write(x/10);
	putchar(x%10+'0');
}
struct Node{
	int l,r,ms,ls,rs,lazy;
}T[N<<2];
inline int max(int a,int b){return a>b?a:b;}
inline void pushup(int p){
	T[p].ls=T[lc].ls,T[p].rs=T[rc].rs;
	if(T[p].ls==T[lc].r-T[lc].l+1)T[p].ls+=T[rc].ls;
	if(T[p].rs==T[rc].r-T[rc].l+1)T[p].rs+=T[lc].rs;
	T[p].ms=max(max(T[lc].ms,T[rc].ms),T[lc].rs+T[rc].ls);
}
inline void pushnow(int p,int v){
	T[p].ls=T[p].rs=T[p].ms=(1-v)*(T[p].r-T[p].l+1);
	T[p].lazy=v;
}
inline void pushdown(int p){
	if(T[p].lazy==-1)return;
	pushnow(lc,T[p].lazy);
	pushnow(rc,T[p].lazy);
	T[p].lazy=-1;
}
inline void build(int p,int l,int r){
	T[p].l=l,T[p].r=r,T[p].lazy=-1,T[p].ls=T[p].rs=T[p].ms=r-l+1;
	if(l==r)return;
	build(lc,l,mid);
	build(rc,mid+1,r);
	pushup(p);
}
inline void update(int p,int ql,int qr,int v){
	if(ql<=T[p].l&&T[p].r<=qr){
		pushnow(p,v);
		return;
	}
	pushdown(p);
	if(qr<=mid)update(lc,ql,qr,v);
	else if(ql>mid)update(rc,ql,qr,v);
	else{
		update(lc,ql,mid,v);
		update(rc,mid+1,qr,v);
	}
	pushup(p);
}
inline int query(int p,int v){
	if(T[p].ms<v)return 0;
	if(T[p].l==T[p].r)return T[p].l;
	pushdown(p);
	if(T[lc].ms>=v)return query(lc,v);
	if(T[lc].rs+T[rc].ls>=v)return mid-T[lc].rs+1;
	return query(rc,v);
}
int n,m;
int main(){
	freopen("hotel.in","r",stdin);
	freopen("hotel.out","w",stdout);
	n=read(),m=read();
	build(1,1,n);
	for(int i=1;i<=m;++i){
		int op=read();
		if(op==1){
			int x=read(),t=query(1,x);
			write(t);
			puts("");
			if(t)update(1,t,t+x-1,1);
		}
		else{
			int x=read(),d=read();
			update(1,x,x+d-1,0);
		}
	}
	return 0;
}

2018.06.29 NOIP模拟 旅馆(线段树)的更多相关文章

  1. 2018.06.29 NOIP模拟 排列(线段树)

    排列(premu.cpp) [题目描述] 对于一个 1 到 n 的排列,逆序数的定义为:排列中第 i 位 ai的逆序数就是 a1-ai-1中比 ai大的数的个数.另外用 pi表示 a1,-,ai的逆序 ...

  2. 2018.06.29 NOIP模拟 Gcd(容斥原理)

    Gcd 题目背景 SOURCE:NOIP2015-SHY-2 题目描述 给出n个正整数,放入数组 a 里. 问有多少组方案,使得我从 n 个数里取出一个子集,这个子集的 gcd 不为 1 ,然后我再从 ...

  3. 2018.06.29 NOIP模拟 Minimum(最小生成树)

    Minimum 题目背景 SOURCE:NOIP2015-SHY-2 题目描述 给出一幅由 n 个点 m 条边构成的无向带权图. 其中有些点是黑点,另外点是白点. 现在每个白点都要与他距离最近的所有黑 ...

  4. 2018.06.29 NOIP模拟 1807(简单递推)

    1807 题目背景 SOURCE:NOIP2015-SHY-2 题目描述 给出一个由数字('0'-'9')构成的字符串.我们说一个子序列是好的,如果他的每一位都是 1.8.0.7 ,并且这四个数字按照 ...

  5. 2018.06.29 NOIP模拟 繁星(前缀和)

    繁星 [问题描述] 要过六一了,大川正在绞尽脑汁想送给小伙伴什么礼物呢.突然想起以前拍过一张夜空中的繁星的照片,这张照片已经被处理成黑白的,也就是说,每个像素只可能是两个颜色之一,白或黑.像素(x,y ...

  6. 2018.06.29 NOIP模拟 边的处理(分治+dp)

    边的处理(side.cpp) [问题描述] 有一个 n 个点的无向图,给出 m 条边,每条边的信息形如<x,y,c,r><x,y,c,r><x,y,c,r>. 给出 ...

  7. 2018.06.29 NOIP模拟 区间(前缀和差量)

    区间(interval.cpp) 时限:2000ms 空间限制:512MB [问题描述] 给出一个长度为 n 的序列 a[1]-a[n]. 给出 q 组询问,每组询问形如<x,y>< ...

  8. 2018.06.26 NOIP模拟 纪念碑(线段树+扫描线)

    题解: 题目背景 SOURCE:NOIP2015−GDZSJNZXSOURCE:NOIP2015-GDZSJNZXSOURCE:NOIP2015−GDZSJNZX(难) 题目描述 2034203420 ...

  9. 2018.06.27 NOIP模拟 节目(支配树+可持久化线段树)

    题目背景 SOURCE:NOIP2015-GDZSJNZX(难) 题目描述 学校一年一度的学生艺术节开始啦!在这次的艺术节上总共有 N 个节目,并且总共也有 N 个舞台供大家表演.其中第 i 个节目的 ...

随机推荐

  1. angular 使用服务共享数据需要注意

    在使用服务共享数据时,需要注意一些细节,否则会出现视图不刷新,也不报错这样的问题,遇到了,总结下 如下: <div ng-controller='ctr1'> <a href={{n ...

  2. 数据恢复软件extundelete介绍

    linux下文件系统一般由文件名.Inode.Block三部分组成.当一个用户在Linux系统中试图访问一个文件时,系统会先根据文件名去查找它的inode,看该用户是否具有访问这个文件的权限.如果有, ...

  3. FileOperator 文件(夹)操作类

    public class FileOperator { /** * 复制文件目录 * @param srcDir 要复制的源目录 eg:/mnt/sdcard/DB * @param destDir ...

  4. html file 文件批量上传 以及碰到的一些问题提

    //javascript 代码 $("#submite").click(function (evt) { var arrayTr = $("#datatables&quo ...

  5. python爬虫(5)--正则表达式

    正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑. 1.了解正则表达式 正则表达式 ...

  6. session会话时间

    session对象失效在下列情况下被删除: A.程序调用HttpSession.invalidate() B.距离上一次收到客户端发送的session id时间间隔超过了session的最大有效时间 ...

  7. js函数中变量声明提前

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  8. 吴裕雄 数据挖掘与分析案例实战(13)——GBDT模型的应用

    # 导入第三方包import pandas as pdimport matplotlib.pyplot as plt # 读入数据default = pd.read_excel(r'F:\\pytho ...

  9. 【Java】JavaIO(二)、节点流

    一.InputStream & outputStream Java字节流主要是以InputStream (输入流),outputStream(输出流)为基类,本身是抽象类不能创建实例,但是是字 ...

  10. List<?>和List<T>的区别

    是java泛型的两种用法:List<T>是泛型方法,List<?>是限制通配符 List<T>一般有两种用途:1.定义一个通用的泛型方法.伪代码: public i ...