P4062

Portal

首先考虑用众数而非区间来贡献答案。我们考虑对每个数都处理出它所在的位置 list,然后对每个 list 独立搞。

一个简单粗暴的想法是,列出两个位置构成的区间满足条件的充要条件,然后发现是一个关于 (i) 的式子和关于 (j) 的式子的不等式,BIT 维护一下就行了,但这样每个是 (mathrm O(nlog)),最坏能被卡到 (Omega!left(n^2 ight))。于是我们要努力让复杂度不关于 (n),只关于当前数的个数。

于是我们一步步来把 (n) 给去掉。首先肯定不能枚举右端点 (j) 了。设当前数的位置 list 为 (a)。于是我们考虑枚举 (a_jsim a_{j+1}-1) 的这个 gap,这样至少枚举量不关于 (n) 了。我们看对于左端点 (i),它右边第一个为 (a_i'),那么它与 (j) 的共同贡献,就看一下它至少要伸多远,和 (a_{j+1}-1) 取个 (min),然后算一下到 (a_j) 的距离与 (0) 取个 (max)。式子列出来:

[max!left(0,min!left(a_{j+1}-1,a_i'+2(j-i+1)-1-1 ight)-a_j+1 ight) ]

比较长的那串整理一下是 (a_i'+2j-2i)。然后有两个 (min/max),考虑分类讨论:

  1. (a_i'+2j-2i<a_{j+1}-1)(a_i'-2i+1<a_{j+1}-2j)。这样里面那个 (min) 的值就是 (a'_i+2j-2i)。然后还要使它 (leq a_j-1),不然会值为 (0),即 (a'_i-2i+1geq a_j-2j),然后值是 (a'_i+2j-2i-a_j+1=left(a'_i-2i+1 ight)+(2j-a_j))。于是这个我们每次将 (a'_i-2i+1) 加入 BIT,然后数一下 ([a_j-2j,a_{j+1}-2j)) 内的计数与和,就可以算了;
  2. (a'_i+2j-2igeq a_{j+1}-1)(a'_i-2i+1geq a_{j+1}-2j)。这样值就是 (a_{j+1}-1-a_j+1=a_{j+1}-a_j),这个只跟 (j) 有关,于是后缀计数一下乘一下即可。

但是这样统计答案的次数是不跟 (n) 有关了,但是加入 BIT 的次数还跟 (n) 有关。于是我们考虑一个 gap 整体加入,那这显然计数是区间加,而和的失职,其实是区间加等差数列。我们考虑线段树维护,那么这个区间加等差数列、区间求和其实是个经典问题,只需要维护懒标记,然后下传的时候就用一下等差数列求和公式就可以了,可以 (mathrm O(log)) 维护。这样总复杂度就是线对了。

然后每次不能重新建树,会 T,必须每次撤销。

code

原文地址:https://www.cnblogs.com/ycx-akioi/p/solution-p4062.html