题解 CF2180G Balance

· · 题解

题解 CF2180G Balance

我们的题解确有问题。截至目前,出题人已经修了 7 个锅了,有两个来自本题:[复杂度]()和[式子细节]()。

其他题

题意

给定初始为空的数组 a,要求支持三种操作:

数据范围:多测,t\le 10^4,\sum q\le 10^6

做法

考虑怎么维护询问的答案。显然通常来说对于所有子序列求的东西拆贡献是比较合适的。

显然最最暴力的求法是枚举每个元素、子序列长度及在子序列中出现的位置,即答案为:

\sum_{i=1}^n\sum_{j=1}^n\sum_{k=1}^j\dfrac{\text{C}_{i-1}^{k-1}\text{C}_{n-i}^{j-k}ka_i}{j}

然后众所周知根据组合意义,\text{C}_{n}^{m}=\text{C}_{n}^{n-m}。又注意到在题目的限制下,这个数组始终是回文的。所以我们可以分别进行正算和反算,写出答案的两倍的式子:

\begin{aligned}&\sum_{i=1}^n\sum_{j=1}^n\sum_{k=1}^j\dfrac{\text{C}_{i-1}^{k-1}\text{C}_{n-i}^{j-k}ka_i}{j}+\sum_{i=1}^n\sum_{j=1}^n\sum_{k=1}^j\dfrac{\text{C}_{n-i}^{j-k}\text{C}_{i-1}^{k-1}(j-k+1)a_i}{j}\\=&\sum_{i=1}^n\sum_{j=1}^n\sum_{k=1}^j\dfrac{\text{C}_{i-1}^{k-1}\text{C}_{n-i}^{j-k}ka_i}{j}+\sum_{i=1}^n\sum_{j=1}^n\sum_{k=1}^j\dfrac{\text{C}_{i-1}^{k-1}\text{C}_{n-i}^{j-k}(j-k+1)a_i}{j}\\=&\sum_{i=1}^n\sum_{j=1}^n\sum_{k=1}^j\dfrac{\text{C}_{i-1}^{k-1}\text{C}_{n-i}^{j-k}(j+1)a_i}{j}\\=&\sum_{i=1}^n\sum_{j=1}^n\sum_{k=1}^j\text{C}_{i-1}^{k-1}\text{C}_{n-i}^{j-k}a_i+\sum_{i=1}^n\sum_{j=1}^n\sum_{k=1}^j\dfrac{\text{C}_{i-1}^{k-1}\text{C}_{n-i}^{j-k}a_i}{j}\end{aligned}

我们发现,加号前面是所有子序列元素和的和,后面是所有子序列平均值的和。所以首先加号前面的部分可以直接写成 2^{n-1}\sum a_i

然后考虑加号后面的部分。当长度 j 定下来的时候,利用范德蒙恒等式 \text{C}_a^b\text{C}_c^d=\text{C}_{a+b}^{c+d} 容易表示出一个数 a_i 的贡献为 \dfrac{\text{C}_{i-1}^{k-1}\text{C}_{n-i}^{j-k}a_i}{j}=\dfrac{\text{C}_{n-1}^{j-1}a_i}{j},加上枚举 a_ij 的过程,得到这部分贡献为

\begin{aligned}&\sum_{i=1}^n\sum_{j=1}^n\dfrac{\text{C}_{n-1}^{j-1}a_i}{j}\\=&\sum_{i=1}^na_i\sum_{j=1}^n\dfrac{\text{C}_{n-1}^{j-1}}{j}\\=&\sum_{i=1}^na_i\sum_{j=1}^n\dfrac{(n-1)!}{j(j-1)!(n-j)!}\\=&\sum_{i=1}^na_i\sum_{j=1}^n\dfrac{n!}{nj!(n-j)!}\\=&\sum_{i=1}^na_i\dfrac{\displaystyle\sum_{j=1}^n\text{C}_{n}^{j}}{n}\end{aligned}

由二项式定理,取 a=b=1 时有 \displaystyle\sum_{j=\mathbf{0}}^n\text{C}_{n}^{j}=2^n,所以上式等于 \displaystyle\sum_{i=1}^na_i\dfrac{2^n-1}{n}

到这里,我们已经把贡献化成了仅与 n\sum a_i 相关的式子,所以我们需要维护的就是这两个值。n 显然是容易维护的,而有了 n 后插入操作的 \sum a_i 也容易维护。所以现在我们需要找到删除操作删掉的到底是谁。

考虑一次插入操作。插入后数组的长度必然变为奇数(这个可以通过分讨插入前的奇偶性证明,这里不展开)。此时,

xoox 的状态出发,我们考虑对于每次插入操作,维护其状态 0/1/2/3,其中插入的时候如果当前长度为偶数则插入 1,否则插入 3。然后删除的时候,从后往前扫每个插入操作,如果某个操作是状态是 0/1 则删掉的就是这个数,将其加 1 并模 4 后停止遍历;反之则将其加 1 并模 4 后继续遍历。

这个过程的均摊复杂度是 O(1) 的。证明考虑维护从中间开始长度为 q 的窗口,这是此时极端情况下能删掉的所有元素。每次插入时必然会将窗口内至少一半的元素替换成操作时间为 O(1)x,而原有部分的时间代价会加一,但含量会减半。所以最终倒数第 k 个加入的二操作在窗口中的含量应该是 \dfrac{q}{2^k},即该次插入操作贡献的总时间代价是 k\dfrac{q}{2^k},对其求和的值为无限接近 2q,方法是注意到 S-\frac{1}{2}S=\sum_k\frac{1}{2^k}=1

所以总复杂度应该是 O(q \log V)。不知道官解里的 \log q 哪来的,可能是算上了快速幂的时间,但快速幂也不是 \log q 的吧(虽然 \log V\log q 没啥区别)……

(upd:出题人把复杂度改过来了)