题目
题目概要
对于一个长度为
n
n
n 的序列,对其进行
m
m
m 次操作,每次操作将一个区间内的所有值赋值为区间内的最大值。
将 m m m 次操作全部告知,对于每组询问 ⟨ l , r , k ⟩ \langle l,r,k\rangle ⟨l,r,k⟩ ,输出进行了 [ l , r ] [l,r] [l,r] 中的所有操作后, a k a_k ak 的值。
数据范围与约定
n
,
m
,
q
≤
1
0
5
n,m,q\le 10^5
n,m,q≤105 。
思路
注意到一个长臂政策:
- 如果先后执行了两次操作 [ l 1 , r 1 ] , [ l 2 , r 2 ] [l_1,r_1],[l_2,r_2] [l1,r1],[l2,r2] ,满足 l 2 ≤ r 1 ≤ r 2 l_2 \le r_1 \le r_2 l2≤r1≤r2,那么 ∀ i ∈ [ l 2 , r 2 ] , a i ′ = max j = l 1 r 2 a j \forall i\in[l_2,r_2],a'_i=\max_{j=l_1}^{r_2}a_j ∀i∈[l2,r2],ai′=j=l1maxr2aj
用一张图片来感受它。
如果先执行
[
l
1
,
r
1
]
[l_1,r_1]
[l1,r1] 的操作,显然的,公共部分
[
l
2
,
r
1
]
[l_2,r_1]
[l2,r1] 就变成了
[
l
1
,
r
1
]
[l_1,r_1]
[l1,r1] 的最大值。
此时再执行 [ l 2 , r 2 ] [l_2,r_2] [l2,r2] ,自然就使用了 max i = l 1 r 1 a i \max_{i=l_1}^{r_1}a_i maxi=l1r1ai 更新整个区间的最大值。
所以说, [ l 2 , r 2 ] [l_2,r_2] [l2,r2] 中的元素都会被替换为 [ l 1 , r 2 ] [l_1,r_2] [l1,r2] 中的最大值。
有了这一点之后,我们可以放心地说,对于一些固定的操作,最终存在某对 l , r l,r l,r ,满足 1 ≤ l ≤ k ≤ r ≤ n , ∀ { a } , a k ′ = max i = l r a i 1\le l\le k\le r\le n,\forall \{a\},a'_k=\max_{i=l}^{r}a_i 1≤l≤k≤r≤n,∀{a},ak′=maxi=lrai 。
找到它的方法也很简单,只需要找,最远的可以传递到 a k a_k ak 的区间是谁。
在代码实现上,我们用树来表示这个关系,一个操作 [ l 1 , r 1 ] [l_1,r_1] [l1,r1] 的父节点是另一个操作 [ l 2 , r 2 ] [l_2,r_2] [l2,r2] ,且该操作满足 l 2 ≤ l 1 ≤ r 2 l_2\le l_1\le r_2 l2≤l1≤r2 ,在此基础上,还要求 [ l 2 , r 2 ] [l_2,r_2] [l2,r2] 的操作时间尽可能靠后,但是保持先于 [ l 1 , r 1 ] [l_1,r_1] [l1,r1] 的操作时间。
如何实现这棵树的维护呢?我们将询问离线下来,按照 r r r 排序,从左到右扫描,每加入一个新的操作区间,就在线段树上将区间内的每个点的 f f f 赋值为当前点。这样一来,一个区间的父节点,就是 f ( l ) f(l) f(l)。
这是左端点,右端点同理。
光是“维护”还不够,我们需要倍增地找到最上面的一个,满足操作时间不小于 l l l 。
复杂度是啥捏?我也不知道诶 😂 大概是 O ( n log n ) \mathcal O(n\log n) O(nlogn) 的,可能有点常数。
代码
我自闭了……
等我有空了,可能会补上的吧。