【题解】小猪佩奇学数学

小猪佩奇学数学

\(\text{Solution:}\)

考虑单位根反演。

\[\frac{1}{k}\sum_{i=0}\binom{n}{i}p^i(i-i\bmod k) \\ \text{Part1:} \\ \sum_{i=0}^n \binom{n}{i}p^i i \\ =np\sum_{i=0}^n \binom{n-1}{i-1}p^{i-1} \\ =np\sum_{j=0}^{n-1} \binom{n-1}{j}p^j \\ =np(1+p)^{n-1} \\ \text{Part2:} \\ \sum_{i=0}^n \binom{n}{i}p^i(i\bmod k) \\ =\sum_{i=0}^n \binom{n}{i}p^i\sum_{j=0}^{k-1} j[j\equiv i(\bmod k)] \\ =\sum_{i=0}^n \binom{n}{i}p^i\sum_{j=0}^{k-1} j[k|i-j] \\ =\sum_{i=0}^n \binom{n}{i}p^i\sum_{j=0}^{k-1} j\frac{1}{k}\sum_{l=0}^{k-1}\omega_k^{l(i-j)} \\ =\frac{1}{k}\sum_{j=0}^{k-1} j\sum_{l=0}^{k-1} \omega_k^{-lj}\sum_{i=0}^n \binom{n}{i}p^i\omega_k^{il} \\ =\frac{1}{k}\sum_{j=0}^{k-1} j\sum_{l=0}^{k-1} \omega_k^{-lj}(1+p\omega_k^l)^n \\ =\frac{1}{k}\sum_{l=0}^{k-1}(1+p\omega_k^l)^n\sum_{j=0}^{k-1}j\omega_k^{-lj} \\ =\frac{1}{k}\sum_{l=0}^{k-1}(1+p\omega_k^l)^n\sum_{j=0}^{k-1}j\frac{1}{(\omega_k^l)^j} \]

后面是等差乘等比数列求和。

复杂度 \(O(k\log n).\)

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod=998244353;
const int g=3;
inline int Add(int x,int y){return (x+y)%mod;}
inline int Mul(int x,int y){return 1ll*x*y%mod;}
inline int qpow(int x,int y){
    int res=1;
    while(y){
        if(y&1)res=Mul(res,x);
        x=Mul(x,x);y>>=1;
    }
    return res;
}
int n,p,k;
int P1,P2;
int num,len=1;
int pwk[1<<21];
inline int getinv(int x){return qpow(x,mod-2);}
signed main(){
    scanf("%lld%lld%lld",&n,&p,&k);
    P1=Mul(n,Mul(p,qpow((1+p)%mod,n-1)));
    while(len<k)len<<=1,num++;
    int Wk=qpow(g,(mod-1)/k);
    pwk[0]=1;
    for(int i=1;i<k;++i)pwk[i]=Mul(pwk[i-1],Wk);
    for(int i=0;i<k;++i){
        int s1=qpow(Add(1,Mul(p,pwk[i])),n);
        int q=pwk[i];
        q=getinv(q);
        if(q==1)P2=Add(P2,Mul(s1,Mul(k,Mul(k-1,getinv(2)))));
        else{
            int pt1=Mul(k,qpow(q,k));
            pt1=Mul(pt1,getinv(q-1));
            int pt2=Mul(q,Add(mod-1,qpow(q,k)));
            pt2=Mul(pt2,getinv(Mul(q-1,q-1)));
            pt2=mod-pt2;
            P2=Add(P2,Mul(Add(pt1,pt2),s1));
        }
    }
    P2=Mul(P2,getinv(k));
    P2=mod-P2;
    P1=Add(P1,P2);
    P1=Mul(P1,getinv(k));
    printf("%lld\n",P1);
    return 0;
}
posted @ 2021-08-16 23:10  Refined_heart  阅读(74)  评论(0编辑  收藏  举报