1 条题解

  • 0
    @ 2025-8-24 22:19:27

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 苹果蓝17
    **

    搬运于2025-08-24 22:19:27,当前版本为作者最后更新于2021-09-16 21:04:38,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题目传送门

    更好的阅读体验

    题意简述

    • 现有 nn 个变量 a1,a2,,ana_1,a_2,\cdots,a_n,给出所有它们能组成的 kk 次轮换式的值 fkf_k,求 i=1naim\sum\limits_{i=1}^n a_i^m

    • n30000,m109n \leq 30000,m \leq 10^9

    题目分析

    轮换式是典型的积和形式,直接考虑写成生成函数:

    fk=[xk]i=1n(1+aix)f_k=[x^k]\prod\limits_{i=1}^n(1+a_ix) F(x)=i=1n(1+aix)F(x)=\prod\limits_{i=1}^n(1+a_ix)

    发现这个累乘很难处理,考虑两边取 ln\ln

    $$\begin{aligned} \ln F(x) & =\sum\limits_{i=1}^n \ln(1+a_ix) \\ & =\sum\limits_{i=1}^n \sum\limits_{j \geq 1} -\dfrac{(-a_ix)^j}{j} \\ & =\sum\limits_{j \geq 1} \dfrac{(-1)^{j+1}}{j} x^j \sum\limits_{i=1}^n a_i^j \end{aligned} $$

    于是答案为:

    Ans=m(1)m+1[xm]lnF(x)Ans=\dfrac{m}{(-1)^{m+1}}[x^m]\ln F(x)

    只需要求出 [xm]lnF(x)[x^m] \ln F(x) 即可。


    mm 过大,肯定不能暴力求,考虑 ln\ln 的递推求法:

    G=lnFG=\ln F G=FFG'=\dfrac{F'}{F} FG=FFG'=F' kfk=i=1kigifkikf_k=\sum\limits_{i=1}^{k} ig_{i}f_{k-i}

    knk \leq n 时,暴力求 ln\ln 即可,时间复杂度 O(nlogn)O(n \log n)

    k>nk > n 时,有 fk=0f_k=0

    $$\begin{aligned} 0 & =\sum\limits_{i=1}^{k} ig_{i}f_{k-i} \\ & =\sum\limits_{i=0}^{k-1} (k-i)g_{k-i}f_i \\ & =\sum\limits_{i=0}^{n} (k-i)g_{k-i}f_i \\ & =kf_0 g_k+\sum\limits_{i=1}^{n} (k-i)g_{k-i}f_i \\ \end{aligned} $$$$kf_0 \cdot g_k=-\sum\limits_{i=1}^n (k-i)f_i \cdot g_{k-i} $$

    这是非常显然的齐次线性递推的形式,总时间复杂度 O(nlognlogm)O(n \log n \log m)

    代码里的 gkg_k 代表实际是 kgkkg_k,会方便一些。

    代码

    ...
    long long n,m;
    long long A[N],F[N],G[N],P[N];
    
    int main(){
    	pre();
    	cin>>n>>m;
    	F[0]=1;
    	for(int i=1;i<=n;i++) F[i]=rd();
    	poly::Ln(G,F,n);
    	for(int i=0;i<=n;i++) G[i]=G[i]*i%mod;
    	for(int i=1;i<=n;i++) P[i]=(mod-F[i])%mod;
    	cout<<Recursion::solve(P,G,m,n+1)*ID(m+1)%mod;
    }
    
    • 1

    信息

    ID
    5332
    时间
    2000ms
    内存
    256MiB
    难度
    7
    标签
    递交数
    0
    已通过
    0
    上传者