题目大意:给定一个长度为 N 的序列,每个点有两种状态 1/0,表示占有和空闲,现支持 first-fit 查询是否有一段连续的长度为 X 的空闲子序列和区间赋值操作。

题解:get到了线段树新技能。。qwq

区间赋值操作和其他线段树一样,维护标记即可。

查询是否有一段连续的长度为 X 的空闲子序列只需要类似于维护区间连续最长字段即可,即:lmx,rmx,mx。first-fit 查询操作需要类似于在线段树上二分的操作,即:若左子树满足条件就走左子树,左右子树能拼接成满足需求的结果则返回,否则遍历右子树。

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=5e4+10; int n,m,opt;
struct node{
#define ls(o) t[o].lc
#define rs(o) t[o].rc
int lc,rc;
int mx,lmx,rmx,tag; // 1 -> all zero 2 -> all one
}t[maxn<<1];
int tot,root;
inline void pushup(int o,int l,int r){
int mid=l+r>>1;
t[o].lmx=t[ls(o)].lmx==mid-l+1?t[ls(o)].lmx+t[rs(o)].lmx:t[ls(o)].lmx;
t[o].rmx=t[rs(o)].rmx==r-mid?t[ls(o)].rmx+t[rs(o)].rmx:t[rs(o)].rmx;
t[o].mx=max(t[ls(o)].rmx+t[rs(o)].lmx,max(t[ls(o)].mx,t[rs(o)].mx));
}
inline void pushdown(int o,int l,int r){
if(!t[o].tag)return;
int mid=l+r>>1;
t[ls(o)].tag=t[rs(o)].tag=t[o].tag;
t[ls(o)].lmx=t[ls(o)].rmx=t[ls(o)].mx=t[o].tag==1?mid-l+1:0;
t[rs(o)].lmx=t[rs(o)].rmx=t[rs(o)].mx=t[o].tag==1?r-mid:0;
t[o].tag=0;
}
int build(int l,int r){
int o=++tot;
if(l==r){t[o].lmx=t[o].rmx=t[o].mx=1;return o;}
int mid=l+r>>1;
ls(o)=build(l,mid),rs(o)=build(mid+1,r);
pushup(o,l,r);
return o;
}
void modify(int o,int l,int r,int x,int y,int flag){
if(l==x&&r==y){
t[o].lmx=t[o].rmx=t[o].mx=flag==1?r-l+1:0;
t[o].tag=flag;
return;
}
int mid=l+r>>1;
pushdown(o,l,r);
if(y<=mid)modify(ls(o),l,mid,x,y,flag);
else if(x>mid)modify(rs(o),mid+1,r,x,y,flag);
else modify(ls(o),l,mid,x,mid,flag),modify(rs(o),mid+1,r,mid+1,y,flag);
pushup(o,l,r);
}
int query(int o,int l,int r,int len){
if(l==r)return l;
int mid=l+r>>1;
pushdown(o,l,r);
if(len<=t[ls(o)].mx)return query(ls(o),l,mid,len);
else if(len<=t[ls(o)].rmx+t[rs(o)].lmx)return mid-t[ls(o)].rmx+1;
else return query(rs(o),mid+1,r,len);
} int main(){
scanf("%d%d",&n,&m);
root=build(1,n);
while(m--){
scanf("%d",&opt);
if(opt==1){
int x;
scanf("%d",&x);
if(t[root].mx<x)puts("0");
else{
int l=query(root,1,n,x);
modify(root,1,n,l,l+x-1,2);
printf("%d\n",l);
}
}else if(opt==2){
int x,y;
scanf("%d%d",&x,&y);
modify(root,1,n,x,x+y-1,1);
}
}
return 0;
}

【洛谷P2894】Hotel 线段树+二分查询的更多相关文章

  1. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  2. 【洛谷】【线段树】P1047 校门外的树

    [题目描述:] 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……,L ...

  3. 【洛谷】【线段树】P1886 滑动窗口

    [题目描述:] 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. [输入格式:] 输入一共 ...

  4. 洛谷 - P1198 - 最大数 - 线段树

    https://www.luogu.org/problemnew/show/P1198 要问区间最大值,肯定是要用线段树的,不能用树状数组.(因为没有逆元?但是题目求的是最后一段,可以改成类似前缀和啊 ...

  5. 【洛谷】【线段树】P1471 方差

    [题目背景:] 滚粗了的HansBug在收拾旧数学书,然而他发现了什么奇妙的东西. [题目描述:] 蒟蒻HansBug在一本数学书里面发现了一个神奇的数列,包含N个实数.他想算算这个数列的平均数和方差 ...

  6. 【洛谷】【线段树】P3353 在你窗外闪耀的星星

    [题目描述:] /* 飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年前,在美丽的集美中学,从我看到你微笑着走出教室,你将头向后仰,柔和的晚霞照耀 ...

  7. 洛谷P5280 [ZJOI2019]线段树

      https://www.luogu.org/problemnew/show/P5280 省选的时候后一半时间开这题,想了接近两个小时的各种假做法,之后想的做法已经接近正解了,但是有一些细节问题理不 ...

  8. 洛谷P3374(线段树)(询问区间和,支持单点修改)

    洛谷P3374 //询问区间和,支持单点修改 #include <cstdio> using namespace std; ; struct treetype { int l,r,sum; ...

  9. 洛谷 P2391 白雪皑皑 线段树+优化

    题目描述: 现在有 \(N\) 片雪花排成一列. Pty 要对雪花进行$ M $次染色操作,第 \(i\)次染色操作中,把\((i*p+q)%N+1\) 片雪花和第\((i*q+p)%N+1\)片雪花 ...

随机推荐

  1. matplotlib之折线图

    1.案例一 # coding=utf-8 from matplotlib import pyplot as plt import random # 设置字体相关 from matplotlib imp ...

  2. Kafka sender消息生产者

    1.pom文件引入Kafka依赖(我用的版本是2.2.2.RELEASE) <dependency> <groupId>org.springframework.kafka< ...

  3. LeetCode.937-重新排序日志数组(Reorder Log Files)

    这是悦乐书的第358次更新,第385篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第220题(顺位题号是937).你有一系列日志.每个日志都是以空格分隔的单词串. 每个日 ...

  4. LoadRunner对sockets报文进行压力测试(脚本设计)

    1. LR新建一个windows sockets项目 2. action中写入测试代码 如: #include "lrs.h" Action() { char *recvbuf; ...

  5. 原生js实现选中所有的checkbox

    <div class="con"> <input name='多选项名称' type='checkbox' value='' id="all" ...

  6. Akka系列(四):Akka中的共享内存模型

    前言...... 通过前几篇的学习,相信大家对Akka应该有所了解了,都说解决并发哪家强,JVM上面找Akka,那么Akka到底在解决并发问题上帮我们做了什么呢? 共享内存 众所周知,在处理并发问题上 ...

  7. 小记---------Hadoop读、写文件步骤,HDFS架构理解

    Hadoop 是一个开源框架,可编写和运行分布式应用处理大规模数据 Hadoop框架的核心是HDFS 和 MapReduce HDFS是分布式文件系统(存储) MapReduce是分布式数据处理模型和 ...

  8. 什么是SQL注入以及mybatis中#{}为什么能防止SQL注入而${}为什么不能防止SQL注入

    1.什么是SQL注入 答:SQL注入是通过把SQL命令插入到web表单提交或通过页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL指令. 注入攻击的本质是把用户输入的数据当做代码执行. 举例如: ...

  9. POJ - 1287 Networking (最小生成树&并查集

    You are assigned to design network connections between certain points in a wide area. You are given ...

  10. chromedriver.exe下载

    淘宝的镜像地址可以下载: https://npm.taobao.org/mirrors/chromedriver/