You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
https://codeforces.com/problemset/problem/484/E?f0a28=1
|
|
|
|
|
https://www.luogu.com.cn/problem/CF484E
|
|
|
|
|
|
|
|
|
|
Q:本题为什么没有使用离散化?主席树到底需不需要离散化??
|
|
|
|
|
|
|
|
|
|
### 一、题目描述
|
|
|
|
|
给我们一组数,并给出$m$个询问,每个询问包括$l,r,w$三个数,询问我们在$l$到$r$这个区间内连续取$w$个数,使这$w$个数中的**最小值**尽可能的**大**,输出这个**最大的最小值**。
|
|
|
|
|
|
|
|
|
|
### 二、解题思路
|
|
|
|
|
首先我们先假设在当前的询问下$x$这个数可以成为连续$w$个数中的最小值($x$一定为某个数的值),然后把数列中大于等于$x$的数标为$1$,小于$x$的数标为$0$,那么如果我们求出这个$01$串中最长的$1$串长度为$s$,且$s>=w$的话,$x$就可以拿去更新当前答案,然后我们就枚举比$x$大的值看是否符合条件,当然这个枚举过程用二分实现。
|
|
|
|
|
|
|
|
|
|
用线段树求一串数中最长的$1$串,应该都做过。所以问题就变成了我们如何来建立这个$01$串,很显然,我们不可能去构造$n$棵线段树。假设有两个数$x,y$且$x>y$那么很显然$y$的$01$串是$x$的$01$串的基础上多添加了几个$1$,所以我们可以用可持续化线段树来维护当前$01$串下的最长$1$串的长度。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 二、个人感悟过程
|
|
|
|
|
|
|
|
|
|
#### 1、主席树为什么要记录$[l,r]$,其它题的主席树也记录了左右边界吗?
|
|
|
|
|
答: 区间内第$k$小的数,也是记录了$l,r$,看来记录$l,r$是通用办法。
|
|
|
|
|
|
|
|
|
|
#### 2、在左前缀,右后缀,连续最大值这样的问题中,左右边界的长度都很关键,是直接记录len,还是通过记录l,r,计算出len?
|
|
|
|
|
答: 既然主席树中都需要记录$l,r$,那么
|
|
|
|
|
```c++
|
|
|
|
|
int len(){
|
|
|
|
|
return r-l+1;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
就是标配了。
|
|
|
|
|
|
|
|
|
|
#### 3、$0$号版本似乎就是个架子,没有真正的内容。真正的内容都是一个一个,通过$insert$装载进来,生成一个个版本的。
|
|
|
|
|
答:事实上是这样的,但这个动作是标配,不能省略。
|
|
|
|
|
|
|
|
|
|
#### 4、 insert和query的参数
|
|
|
|
|
p参数都表示以此版本的线段树,是以p号节点为根节点的。
|
|
|
|
|
|
|
|
|
|
#### 5、insert和query的返回值
|
|
|
|
|
insert:返回的是新增加一个数值后,新创建的版本对应的根节点编号q
|
|
|
|
|
query:返回的是一个查询拼接后的结构体,以便读取mx,lx,rx等信息。
|
|
|
|
|
|
|
|
|
|
|