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.

40 lines
2.3 KiB

2 years ago
https://codeforces.com/problemset/problem/484/E?f0a28=1
https://www.luogu.com.cn/problem/CF484E
Q:本题为什么没有使用离散化?主席树到底需不需要离散化??
### 一、题目描述
给我们一组数,并给出$m$个询问,每个询问包括$lrw$三个数,询问我们在$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等信息。