论生成函数对序列高阶差分与高阶前缀和求解的优化
对于给定序列 \(\{a_n\},n\geq 1\) ,需要快速求解其 \(k\) 阶差分或 \(k\) 阶前缀和。
生成函数可对 \(O(kn)\) 的朴素算法进行优化。
先考虑差分:
我们不妨拓宽定义 \(a_0=0,a_m=0(m>n)\)
定义 \(\{a_n\}\) 的 OGF 为 \(\displaystyle A(x)=\sum_{n=0}^\infty a_nx^n\)
设其差分序列 \(\{d_n\}\) 满足 \(d_0=0,d_n=a_n-a_{n-1}(n>0)\) , OGF 为 \(\displaystyle D_1(x)=\sum_{n=0}^\infty d_nx^n\)
可以比较显然的发现 \(\displaystyle D_1(x)=\sum_{n=0}^\infty d_nx^n=\sum_{n=1}^\infty (a_n-a_{n-1})x^n=A(x)-xA(x)=(1-x)\cdot A(x)\)
因此可以进一步得到 \(D_k(x)=(1-x)\cdot D_{k-1}(x)=\cdots =(1-x)^k\cdot A(x)\)
只要展开即可得到高阶差分的值
考虑前缀和:
法一:
设该序列前缀和序列 \(\{s_n\}\) 满足 \(\displaystyle s_n=\sum_{i=1}^n a_i(n\geq 0)\) , OGF 为 \(\displaystyle S_1(x)=\sum_{n=0}^\infty s_nx^n\)
代入 \(s_n\) 的定义式为 \(\displaystyle S_1(x)=\sum_{n=0}^\infty (\sum_{i=0}^na_i)x^n\)
令 \(e_n=1(n\geq 0)\) ,且 OGF 为 \(\displaystyle E(x)=\sum_{n=0}^\infty e_nx^n=\sum_{n=0}^\infty x^n={1\over 1-x}\)
原式变换为 \(\displaystyle S_1(x)=\sum_{n=0}^\infty (\sum_{i=0}^na_ie_{n-i})x^n=\sum_{n=0}^\infty (\sum_{i+j=0}^na_ie_j)x^n\)
系数显然满足卷积的性质,故得到 \(\displaystyle S_1(x)=(\sum_{n=0}^\infty a_nx^n)\cdot (\sum_{n=0}^\infty e_nx^n)={1\over 1-x}\cdot A(x)\)
法二:
显然 \(A(x)\) 为 \(S_1(x)\) 差分形成,故 \((1-x)\cdot S_1(x)=A(x)\) 从而得到 \(S_1(x)={1\over 1-x}A(x)\)
进而可得 \(S_k(x)={1\over 1-x}S_{k-1}(x)=\cdots ={1\over (1-x)^k}\cdot A(x)\)
只要展开即可得到高阶前缀和的值
由于高阶差分与高阶前缀和性质相似,故下文不再分开讨论,并统一以 \(A_k(x)=(1-x)^k\cdot A(x)\) 表示
当 \(k<0\) 时,\(A_k(x)={1\over (1-x)^{|k|}}\cdot A(x)\) ,为 \(k\) 阶前缀和
当 \(k>0\) 时,\(A_k(x)=(1-x)^{|k|}\cdot A(x)\) ,为 \(k\) 阶差分
当 \(k=0\) 时,\(A_k(x)=A(x)\)
当类似原题,需求解前 \(n\) 项时,相当于给定 \(A(x)\) 与 \(k\) ,求解 \(A_k(x)\equiv (1-x)^k\cdot A(x)\pmod {x^n}\)
设 \(B(x)\equiv (1-x)^k\pmod {x^n}\) ,则 \(A_k(x)\equiv B(x)\cdot A(x)\pmod {x^n}\) 可以用 FFT 或者 NTT 求解,复杂度为 \(O(n\log n)\)
法一:
由于 \(B(x)\equiv (1-x)^k\pmod {x^n}\) ,且对 \(\forall k\in Z,(1-x)^k\equiv 1\pmod x\)
故直接两边取对数 \(\displaystyle \ln B(x)\equiv k\cdot \ln(1-x)\pmod x^n\equiv -k\cdot \int(\sum_{i=0}^\infty x^i)\text dx\pmod {x^n}\)
因此 \(\displaystyle B(x)\equiv \exp[-k\cdot \int(\sum_{i=0}^\infty x^i)\text dx]\pmod {x^n}\)
使用多项式积分、多项式指数函数即可求解,复杂度为 \(O(n\log n)\)
法二:
考虑将 \((1-x)^k\) 用广义牛顿二项式定理展开:\(\displaystyle (1-x)^k=\sum_{n=0}^\infty \left( \begin{matrix} k \\ n \end{matrix} \right)\cdot (-1)^nx^n\)
求解出前 \(n\) 项即可
又由于 \(B[n]=\left( \begin{matrix} k \\ n \end{matrix} \right)\cdot (-1)^n=(-1)^n\cdot {k!\over n!(k-n)!}\)
故 \(B[n+1]=(-1)^{n+1}\cdot {k!\over (n+1)!(k-n-1)!}={n-k\over n+1}B[n],B[0]=1\)
因此, \(O(n)\) 预处理 \(1\)~\(n\) 逆元,而后 \(O(n)\) 递推即可求解 \(B(x)\)
不难发现,生成函数优化过的,对于高阶差分与高阶前缀和的求解,复杂度为 \(O(n\log n)\) ,与阶数 \(k\) 无必然关系
故当阶数 \(k>>\log n\) 时,显然优化过后的解法更优
- 若对于某常数 \(C\) ,使得 \(a_n=C\) 恒成立,求 \(k\) 阶差分(\(k<0\) 时代表前缀和)
其本身可视为 \(a_0=C,a_n=0(n>0)\) 的一阶前缀和
故求解该序列 \(k\) 阶差分,等效于求解差分序列 \((k-1)\) 阶差分
又因为 \(D_1(x)=C,A_k(x)=(1-x)^{k+1}D_1(x)=C\cdot B(x)\) ,可 \(O(n)\) 递推求出 \(A_k[n]=C\cdot B[n]\)
- 若对于某常数 \(C\) ,使得 \(a_n=C,n\geq m\) 恒成立,求 \(k\) 阶差分
其本身可视为 \(A(x)=x^m\cdot {A(x)\over x^m}\) ,其中 \({A(x)\over x^m}[n]=C,n\geq 0\)
推法同上,也为 \(O(n)\)
- 若对于某序列 \(\{a_n\}\) ,支持两种操作:
(1). 将某个指定的 \(a_i\) 增加常数 \(c\)
(2). 将整个序列求前缀和或差分
保证操作 \(1\) 全在操作 \(2\) 前,求最后的序列
不妨设所有操作 \(1\) 结束后,序列 \(\{a_n\}\) 变为序列 \(\{a_n+b_n\}\)
之后求解前缀和或差分,则可记录 \((1-x)^k\) 指数,最后直接相乘求解。不妨设操作 \(2\) 结束后,指数为 \(k\) 。
则 \(Ans(x)=(1-x)^k[A(x)+B(x)]=A_k(x)+B_k(x)\)
可以见得, \(1\) 操作实际上对答案的影响为线性的,可以单独处理
- 若对于某序列 \(\{a_n\}\) ,支持两种操作:
(1). 将某个指定的 \(a_i\) 增加常数 \(c\)
(2). 将整个序列求前缀和或差分
求最后的序列
可以先求解出 \(A_k(x)\) ,之后单独考虑每次增加操作,设第 \(i\) 次操作位置为 \(p_i\) ,增加的值为 \(c_i\) ,之后的指数为 \(k_i\)
则由上面的线性可知,对答案的贡献为 \(B_i(x)=c_i\cdot x^{p_i}\cdot (1-x)^{k_i}\)
- 若对于某序列 \(\{a_n\}\) ,支持两种操作:
(1). 将某个指定的区间 \([l,r]\) 所有 \(a_i\) 增加常数 \(c\)
(2). 将整个序列求前缀和或差分
求最后的序列
不妨在所有操作前先将整个序列进行一次前缀和,之后的 \(1\) 操作等效于将位置 \(p_{l_i}\) 的值增加 \(c_i\) ,并将位置 \(p_{r_i+1}\) 的值增加 \((-c_i)\)
考虑最后进行一次差分还原,其余操作同上
- 若对于某初始时恒为 \(0\) 的序列 \(\{a_n\}\) ,支持三种操作:
(1). 将某个指定的区间 \([l,r]\) 所有 \(a_i\) 增加常数 \(c\)
(2). 将整个序列求前缀和或差分
(3). 查询当前子区间 \([l,r]\) 的和
保证操作 \(3\) 数量较少
考虑离线 \(3\) 操作,对于每次该操作,考虑所有其前面的修改对该区间值的影响。
而若某次修改 \(i\) ,使得位置 \(p_i\) 增加 \(c_i\) ,之后进行了 \(k_i\) 阶差分
则对该询问的贡献为 \(c_i\cdot x^{p_i}\cdot (1-x)^{k_i}\) 的 \([l,r]\) 项
由于该部分项相加为 \(\displaystyle c_i\cdot \sum_{j=l}^r(-1)^{j-p_i} \left( \begin{matrix} k_i \\ j-p_i \end{matrix} \right) =c_i\cdot \sum_{j=l-p_i}^{r-p_i}(-1)^j \left( \begin{matrix} k_i \\ j \end{matrix} \right)\)
考虑 \(k_i<0\) 时,具有性质 \((-1)^j \left( \begin{matrix} k_i \\ j \end{matrix} \right)= \left( \begin{matrix} k_i+j-1 \\ k_i-1 \end{matrix} \right)\)
此时 \(\displaystyle c_i\cdot \sum_{j=l-p_i}^{r-p_i}(-1)^j \left( \begin{matrix} k_i \\ j \end{matrix} \right)= c_i\cdot \left( \begin{matrix} k_i+l-p_i-1 \\ k_i \end{matrix} \right)+ c_i\cdot \sum_{j=l-p_i}^{r-p_i} \left( \begin{matrix} k_i+j-1 \\ k_i-1 \end{matrix} \right)- c_i\cdot \left( \begin{matrix} k_i+l-p_i-1 \\ k_i \end{matrix} \right)\)
\(\left( \begin{matrix} n \\ m-1 \end{matrix} \right)+ \left( \begin{matrix} n \\ m \end{matrix} \right)= \left( \begin{matrix} n+1 \\ m \end{matrix} \right)\)
\(\displaystyle \left( \begin{matrix} n \\ m \end{matrix} \right)+\sum_{i=0}^t \left( \begin{matrix} n+i \\ m-1 \end{matrix} \right)= \left( \begin{matrix} n+1 \\ m \end{matrix} \right)+\sum_{i=0}^{t-1} \left( \begin{matrix} n+1+i \\ m-1 \end{matrix} \right)= \cdots= \left( \begin{matrix} n+t \\ m \end{matrix} \right)\)
故 \(\displaystyle c_i\cdot \sum_{j=l-p_i}^{r-p_i}(-1)^j \left( \begin{matrix} k_i \\ j \end{matrix} \right)= c_i\cdot \left( \begin{matrix} k_i+r-p_i \\ k_i \end{matrix} \right)- c_i\cdot \left( \begin{matrix} k_i+l-p_i-1 \\ k_i \end{matrix} \right)\)