题意简述
给一个长度为 $n$ 的序列 $a$,支持 $q$ 个操作:I l r x
区间元素整体 $+x$。
R l r
区间元素整体 $\times (-1)$
Q l r x
询问:从 $[l,r]$ 中选择 $x$ 个数的积的所有方案的和,$\bmod 19940417$。
$n,q\le 5\times 10^4$。
所有操作保证 $[l,r]$ 有意义。操作 I
中,$x\le 10^9$;操作 Q
中,$x\le min(r-l+1,20)$
思路
我们观察到 $x\le 20$。不妨在线段树中维护每一种情况的答案。设 $S[x]$ 表示当前节点中选择 $x$ 个数的积的所有方案的和。为了方便考虑,设 $S[0]=1$。然后,显然还需要维护取相反数的标记和加法标记。
然后开始线段树传 统 艺 能了。
如何合并左右儿子的答案
我们在左半边选 $a$ 个,右半边选 $b$ 个,那就一共选了 $a+b$ 个,贡献是 $lS[a]\times rS[b]$。其中 $lS,rS$ 表示左儿子,右儿子的 $S$ 数组。
如何单节点加值
我们其实就是要考虑这样一个东西:
$a_1\times a_2\cdots \times a_m$ 如何变成 $(a_1+x)(a_2+x)\cdots (a_m+x)$
每个括号里可能是 $a_i$,也可能是 $x$。
枚举 $i$ 个括号出了 $a_i$,剩下 $m-i$ 个括号出了 $x$,贡献为:
(a 中选 i 个数的积的所有方案的和)
$\times x^{m-i}$。
那么,$S[m]$ (不要想歪)该怎么算呢?还是不好算。
其实是因为还差一步转换:我们考虑每个 $i$ 给 $m$ 的贡献。
根据上面的式子,当前的 $i$ 会给 $S[m]$ 加上 $S[i]\times x^{m-i}$ 。那么,加了多少遍呢?我们上面假设现在钦定了 $i$ 个括号出了 $a_i$,然后剩下 $m-i$ 个括号出了 $x$。剩下 $m-i$ 个括号显然不是唯一确定的,那么它们有多少种选择呢?显然是 $C_{len-i}^{m-i}$。其中 $len$ 表示线段树当前区间的长度。
于是,
如何单节点取反
显然,取反只会改变正负性,不改变绝对值,而且只有奇数位置会被改变正负性。
即:对于奇数的 $i$,$S[i]$ 变为 $-S[i]$。
到此,这题涉及到的全部操作都解决了。
代码
1 |
|