IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【LuoguP2894】HOTEL(线段树) -> 正文阅读

[数据结构与算法]【LuoguP2894】HOTEL(线段树)

传送门

Description

??? n n n个空房间,支持两种操作:

1、询问是否有连续 k k k个空房间,若有返回最小起点,并将此k个连续空房间住满;

2、将一段区间内的房间变空。

Solution

???线段树维护区间最长连续空房间长度 v a l val val,原理同维护最大子段和,需要维护每个区间从左端点起的最大连续空房间长度 l s u m lsum lsum、从右端点起的最大连续空房间长度 r s u m rsum rsum

???查询时若当前节点的 v a l > k val>k val>k ,说明一定有解。寻找最左边的起点时可分为三种情况:

(1)k个连续空房间全部位于左子树上,此时递归左子树;
(2)k个连续空房间 部分位于左子树上,部分位于右子树上,此时可以直接计算出起点并返回;
(3)k个连续空房间全部位于右子树上,此时递归右子树。

#include<bits/stdc++.h>
#define MAXN 50005
using namespace std;
inline int Fread(){
	int val=0;bool sign=false;char ch;
	while(~(ch=getchar()) && (ch<'0' || ch>'9') && (ch^'-'));
	val=(sign=!(ch^'-'))?0:ch^48;
	while(~(ch=getchar()) && (ch>='0' && ch<='9'))	val=(val<<1)+(val<<3)+(ch^48);
	return sign?~val+1:val;
}
int n,m;
struct Tree{
	int l,r,val,lsum,rsum,lazy;
}tr[MAXN<<3];
inline void push_up(int k){
	tr[k].lsum=tr[k<<1].lsum==tr[k<<1].r-tr[k<<1].l+1?tr[k<<1].lsum+tr[k<<1|1].lsum:tr[k<<1].lsum;
	tr[k].rsum=tr[k<<1|1].rsum==tr[k<<1|1].r-tr[k<<1|1].l+1?tr[k<<1].rsum+tr[k<<1|1].rsum:tr[k<<1|1].rsum;
	tr[k].val=max(max(tr[k<<1].val,tr[k<<1|1].val),tr[k<<1].rsum+tr[k<<1|1].lsum);
}
inline void push_down(int k){
	if(tr[k].lazy==1){
		tr[k<<1].lazy=tr[k<<1|1].lazy=1;
		tr[k<<1].lsum=tr[k<<1].rsum=tr[k<<1].val=tr[k<<1].r-tr[k<<1].l+1;
		tr[k<<1|1].rsum=tr[k<<1|1].lsum=tr[k<<1|1].val=tr[k<<1|1].r-tr[k<<1|1].l+1;
	}
	else{
		tr[k<<1].lazy=tr[k<<1|1].lazy=2;
		tr[k<<1].lsum=tr[k<<1].rsum=tr[k<<1].val=tr[k<<1|1].rsum=tr[k<<1|1].lsum=tr[k<<1|1].val=0;
	}
	tr[k].lazy=0;
}
void build(int k,int l,int r){
	tr[k].l=l,tr[k].r=r;
	if(l==r){
		tr[k].val=tr[k].lsum=tr[k].rsum=1;
		return;
	}
	int mid=l+r>>1;
	build(k<<1,l,mid),build(k<<1|1,mid+1,r);
	push_up(k);
}
void update(int k,int l,int r,int tp){
	if(l<=tr[k].l && r>=tr[k].r){
		if(tp==1)	tr[k].lsum=tr[k].rsum=tr[k].val=tr[k].r-tr[k].l+1;
		else	tr[k].lsum=tr[k].rsum=tr[k].val=0;
		tr[k].lazy=tp;
		return;
	}
	if(tr[k].lazy)	push_down(k);
	int mid=tr[k].l+tr[k].r>>1;
	if(l<=mid)	update(k<<1,l,r,tp);
	if(r>mid)	update(k<<1|1,l,r,tp);
	push_up(k);
}
int query(int k,int x){
	if(tr[k].l==tr[k].r)	return tr[k].l;
	if(tr[k].lazy)	push_down(k);
	int mid=tr[k].l+tr[k].r>>1;
	if(tr[k<<1].val>=x)	return query(k<<1,x);
	if(tr[k<<1].rsum+tr[k<<1|1].lsum>=x)	return mid-tr[k<<1].rsum+1;
	return query(k<<1|1,x);
}
signed main(){
	n=Fread(),m=Fread();
	build(1,1,n);
	while(m--){
		int opt=Fread();
		if(opt==1){
			int x=Fread(),q=tr[1].val>=x?query(1,x):0;
			printf("%d\n",q);
			if(q)	update(1,q,q+x-1,2);
		}
		else{
			int x=Fread(),y=Fread();
			update(1,x,x+y-1,1);
		}
	}
	return 0;
} 

? ? ?最近做了点线段树,结果美团杯刚上来就把easy难度的数据结构给扔了,感谢队友还配合我表演了一会儿。昨晚看jls直播时听到罗国杰老师讲线段树的起源,感觉挺有趣的。看完直播心力憔悴鸽了cf,找了道题对着屏幕调了半天调出一堆sb错误,果然log2r只有三行码力thm不会变。
? ? ?多校前会出个Segtree相关的合集(咕咕),多校会更新解题和补题报告(kmm说的)。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-13 17:44:00  更:2021-07-13 17:46:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 19:31:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码