简单记录一下div2 825的一个好题 ~ ~。
一个长度为 m m m 的序列 b b b是好序列,当且仅当对于所有的 i , ( 1 ≤ i ≤ m ) i,(1 \le i \le m) i,(1≤i≤m), b i ≤ i b_i \le i bi≤i。
现在求序列 a a a 的所有连续子序列中,好序列有多少个。
记 f i f_i fi为:以 a i a_i ai 为结尾的好序列 [ a j . . a i − 1 a i ] [a_j..a_{i - 1}a_i] [aj..ai−1ai]的个数。
根据定义 f i = j 的取值方案数 = l e n ( [ a j . . a i − 1 a i ] ) ≤ a i f_i =j的取值方案数= len([a_j..a_{i - 1}a_i]) \le a_i fi=j的取值方案数=len([aj..ai−1ai])≤ai
再根据转移递推关系, f i f_i fi的所有合法方案可以从 f i − 1 f_{i -1} fi−1 的合法方案后面接一个 a i a_i ai 以及序列 [ a i a_i ai] 得来,所以 f i ≤ f i − 1 + 1 f_i \le f_{i-1}+1 fi≤fi−1+1。
f i = m i n ( f i − 1 + 1 , a i ) 。 f_i = min(f_{i - 1} + 1, a_i)。 fi=min(fi−1+1,ai)。
答案为 ∑ i = 1 n f i \sum_{i=1}^{n}f_i ∑i=1nfi
接 题意1,给定 q q q 个 独立的 询问:p x
。
令 a p : = x a_p := x ap:=x。
求序列 a a a 的连续子序列中好序列的个数。
仔细观察,可以发现,对于 a p a_p ap 改变之后, f 1.. ( p − 1 ) f_{1..(p-1)} f1..(p−1) 的值并不会改变。
所以,我们只要关注 f p . . n f_{p..n} fp..n 如何改变。
根据 f f f 序列的计算方法,我们可以得出修改后的 f p = m i n ( f p − 1 + 1 , x ) f_p = min(f_{p - 1}+1,x) fp=min(fp−1+1,x)
此时 f f f中, f p f_p fp之后的一段序列 会变成形如 [ f p , f p + 1 + 1 , f p + 2 + 2 , . . . , f p + k + k ] [f_p ,f_{p + 1} + 1,f_{p + 2}+2,...,f_{p +k}+k] [fp,fp+1+1,fp+2+2,...,fp+k+k]。
我们需要知道 k k k 是多少。
由 f i f_i fi 的计算公式,可以推测出:
k k k 就是满足条件 a p + d ≤ f p + d a_{p + d} \le f_p + d ap+d≤fp+d 中 d d d 的最小值减1 (二分可得)。
形式上可以这样理解:在 f d + p f_{d+p} fd+p 之前,所有 f j ( p ≤ j ≤ p + d ) f_j (p \le j\le p+d) fj(p≤j≤p+d) 的最大值约束都来自 f p f_p fp。
从 f d + p f_{d + p} fd+p 开始, f j ( d + p ≤ j ≤ n ) f_j(d + p \le j \le n) fj(d+p≤j≤n) 的最大值约束一开始来自 a d + p a_{d+p} ad+p。
故,令 f d + p = a d + p f_{d+p} = a_{d+p} fd+p=ad+p, 然后重新按照转移方程计算所有的 f j ( j ≥ p + d ) f_j(j \ge p + d) fj(j≥p+d)。
我们可以先预处理所有的,令 f i = a i f_{i} = a_{i} fi=ai, s u m i = ∑ j = i n f j sum_i = \sum_{j=i}^{n}f_j sumi=∑j=infj。
可以倒着预处理,当我们令 f i = a i f_i = a_i fi=ai时, f i f_i fi 之后的一段序列会变成形如 [ f i , f i + 1 + 1 , f i + 2 + 2 , . . . , f i + k + k ] [f_i ,f_{i + 1} + 1,f_{i+2}+2,...,f_{i +k}+k] [fi,fi+1+1,fi+2+2,...,fi+k+k]。
这一点与上面提到的修改操作一样,若 p = k + 1 p = k + 1 p=k+1, 此时 s u m p sum_p sump已经求得。
所以 s u m i = Σ [ f i , f i + 1 + 1 , f i + 2 + 2 , . . . , f i + k + k ] + s u m p sum_i = \Sigma [f_i ,f_{i + 1} + 1,f_{i+2}+2,...,f_{i +k}+k] +sum_p sumi=Σ[fi,fi+1+1,fi+2+2,...,fi+k+k]+sump
其中 Σ [ f i , f i + 1 + 1 , f i + 2 + 2 , . . . , f i + k + k ] \Sigma [f_i ,f_{i + 1} + 1,f_{i+2}+2,...,f_{i +k}+k] Σ[fi,fi+1+1,fi+2+2,...,fi+k+k] 是一个等差数列和。
完成预处理之后,根据上文的分析,可以得出,询问的答案会变成:
∑ i = 1 p f i + ∑ [ f i + 1 + 1 , f i + 2 + 2 , . . . , f i + k + k ] + s u m k + 1 \sum_{i = 1}^{p}f_i+\sum [f_{i + 1} + 1,f_{i+2}+2,...,f_{i +k}+k]+sum_{k +1} ∑i=1pfi+∑[fi+1+1,fi+2+2,...,fi+k+k]+sumk+1
本题中对序列f的二分,可以使用线段树上二分或者st表 + 二分答案实现,具体实现方法已经广为人知,就不做补充了。