「题解」序列操作
描述
思路
用线段树维护,设 \(f_{u,k}\) 为在 \(u\) 结点选出 \(k\) 个数相乘,所有乘积的总和。
向上合并时显然 \(f_{u,k}=\sum_{i=0}^{k}f_{l,i}\cdot f_{r,k-i}\)。
接下来考虑区间取反操作,## 描述
思路
用线段树维护,设 \(f_{u,k}\) 为在 \(u\) 结点选出 \(k\) 个数相乘,所有乘积的总和。
向上合并时显然 \(f_{u,k}=\sum_{i=0}^{k}f_{l,i}\cdot f_{r,k-i}\)。
接下来考虑区间取反操作,容易发现,当 \(k\) 为偶数时,\(-1\) 全部抵消,不会有任何影响;当 \(k\) 为奇数时,\(f_{u,k}=-f_{u,k}\)。
区间加操作是本题的灵魂。举一个例子以助于更好地理解。\(k=3\),操作前的序列为 \(\{a_1,a_2,a_3,a_4\}\),这一次操作是整体加 \(v\)。也就是要从 \(\{a_1+v,a_2+v,a_3+v,a_4+v\}\) 中选取 \(3\) 个数,计算乘积的总和,即计算 \((a_1+v)(a_2+v)(a_3+v)+(a_1+v)(a_2+v)(a_4+v)+(a_1+v)(a_3+v)(a_4+v)+(a_2+v)(a_3+v)(a_4+v)\)。
可以看作在 \(n\) 个数中选出了 \(c\) 个分为一组,有若干组。
枚举再每一组中选了 \(j\) 个 \(v\),选了 \(k-j\) 个原来的 \(a\),每一组的答案为 \(v\times(\) 在这一组中选出 \(k-j\) 个数的乘积之和 \()\)。
当 \(j=1\) 时,对应到例子上来,就是 \(v(a_2a_3+a_1a_3+a_1a_2)+v(a_2a_4+a_1a_4+a_1a_2)+v(a_3a_4+a_1a_4+a_1a_3)+v(a_3a_4+a_2a_4+a_2a_3)\)。
我们要求出每一组的任意 \(k-j\) 个数的乘积的方案,在所有组的方案中出现了多少次。
可以发现,这要一个组中出现了这 \(k-j\) 个数,那么它的所有方案中也有且仅有一个方案包含这 \(k-j\) 个数。
于是,就相当于固定住了这 \(k-j\) 个数,剩下的数随便选。