考虑值域从小往大扫,同时维护另一个序列 bb,扫过的地方 bb 对应的位置改成 11,那么一对位置 (i,k) (ai=ak)(i, k) \ (a_i = a_k) 的贡献是 bikb_{i \sim k} 的和。

显然每种 aia_i 对应的位置对 (i,k)(i, k) 贡献是独立的,那么我们只考虑一种。假设这种数 xx 的出现次数为 CC,出现位置分别为 p1Cp_{1 \sim C},设 bpipi+1b_{p_i \sim p_{i + 1}} 的和为 cic_i

我们有两种方法统计这种贡献:

  1. 暴力拆出 C2C^2 个位置对,变为二维偏序。它的优点在于可以和其他贡献一起跑。
  2. O(n)O(n) 预处理后给每个询问 O(1)O(1) 计算贡献。具体来说,对于区间 [L,R][L, R] 的询问,我们找到 L,RL, R 对应的关键点 pl,prp_l, p_r,那么这个询问对应的贡献是 i=lr1ci(il+1)(ri)\sum_{i = l}^{r - 1} c_i(i - l + 1)(r - i)。预处理出 ci,i×ci,i2×cic_i, i \times c_i, i^2 \times c_i 的前缀和即可 O(1)O(1) 查询。找关键点的时候不能二分,也需要 O(n)O(n) 预处理出来。

设置阈值 BBCBC \le B 时用第一种方法,C>BC > B 时用第二种方法。后者的总时间复杂度显然是 O(nB(n+q))O(\frac nB(n + q)),前者可以平衡一下做到 O(nB+qn)O(nB + q\sqrt n)。解出 B=nB = \sqrt n 时总时间复杂度为 O((n+q)n)O((n + q)\sqrt n)。因为要扫描线所以不支持强制在线,被莫队做法打爆了。