agc037_f Counting of Subarrays

agc037_f Counting of Subarrays

https://atcoder.jp/contests/agc037/tasks/agc037_f

https://img.atcoder.jp/agc037/editorial.pdf

Snipaste_2020-02-09_16-19-59.png

Snipaste_2020-02-09_16-20-13.png

Tutorial

我们称一个序列为合法序列当且仅当存一个 (K) 使得它是 ((K,L))

考虑如何判断一个序列 ((A_1,A_2, cdots , A_N)) 是否合法, 假如 (N=1) , 那么它是合法的,否则

  • 判断如果整个序列相等,那么当 (N ge L) 时, 序列合法
  • 否则, 设 (m)(A) 中最小的数, 令 ([l_1,r_1] cup cdots cup [l_k, r_k])(A) 中值为 (m) 的元素的位置集合((r_i+1<l_{i+1}))
  • 如果存在一个区间 ([l_i,r_i]) 的大小 (<L) , 那么这不是一个合法序列
  • 否则, 对于每个区间 ([l_i,r_i]) 将其替换为 ([dfrac {r_i - l_i + 1}L])(m+1) , 回到第一步重新判断.

如果直接这样判断, 我们用set维护元素的位置集合, 那么每次新增加一个元素时需要删除 (L) 个元素, 复杂度为 (O(N log N))

回到原本的问题, 如何统计有多少连续子序列是合法序列, 注意如果 (Y)(X) 的连续子序列, 那么我们在对 (Y) 进行上面的判断步骤时, 中间部分的序列也是 (X) 中间部分的子序列, 所以我们对整个序列进行如上的判断, 需要考虑如何计算.

我们将这个问题描述为, 给出 (L_1, cdots, L_n, R_1, cdots, R_n) , 对于所有合法子序列 (A_i, cdots A_j) 计算 (L_iR_j) 的和.

  • 如果整个序列的元素相等, 答案为所有满足 (i = j)(j-i+1 ge L)((i,j))(L_iR_j) 的和, 这部分可以线性计算
  • 否则与上面类似的定义 (m)(l_1,r_1 , cdots l_k,r_k)
  • 对于每个 (i) 考虑 ([l_i,r_i]) 中的合法子序列 ([p,q])(L_p,R_q) 的和
  • 对于每个 (i) , 替换 ([l_i,r_i])([dfrac {r_i-l_i+1}L])(m+1) 与适当的一些 (L,R)
  • 递归对其计算

考虑如何确定新的 (L,R) , 利用下面的例子感性理解一下

Snipaste_2020-02-09_16-44-31.png

注意我们新加入的区间里的子区间的答案在这一层已经统计过了,需要减去

复杂度 (O(N log N))

原文地址:https://www.cnblogs.com/ljzalc1022/p/13191058.html