LGP5591题解

题意很明确,不说了。

前置芝士:单位根反演

也就是:

\[[n|a]=\frac 1 n \sum_{i=0}^{n-1}w_n^{ai} \]

看到题目给的柿子:

\[\sum_{i=0}^n\binom n i \times p^i \times \lfloor \frac i k \rfloor \]

先把那个向下取整拆开:

\[\sum_{i=0}^n\binom n i \times p^i \times \frac {i- i \bmod k} k \]

\[\frac 1 k \times (\sum_{i=0}^n\binom n i \times p^i \times i - \sum_{i=0}^n\binom n i \times p^i \times i \bmod k) \]

先看左边的:

\[\sum_{i=0}^n \binom n i\times p^i \times i \]

由于 \(i\) 这里很难使用二项式定理,又不能爆算,所以考虑通过某种方式把 \(i\) 搞掉,给出引理:

\[\binom n m m = \binom {n-1} {m-1} n \]

证明是:

\[\binom n m = \frac {n!} {(n-m)!m!}m = \frac {(n-1)!} {(n-m)!(m-1)!}n = \binom {n-1} {m-1}n \]

于是:

\[np\sum_{i=0}^n\binom {n-1} {i-1} p^i \]

然后使用二项式定理:

\[np(p+1)^{n+1} \]

现在看向右边:

\[\sum_{i=0}^n\binom n i \times p^i \times i \bmod k \]

按照做莫反题的经验,枚举余数:

\[\sum_{i=0}^n\binom n i p^i\sum_{t=0}^{k-1}t[i-t \bmod k =0] \]

单位根反演一下:

\[\frac 1 k\sum_{i=0}^n\binom n i p^i\sum_{t=0}^{k-1}t\sum_{j=0}^{k-1}w_k^{(i-t)j} \]

\[\frac 1 k\sum_{i=0}^n\binom n i p^i\sum_{t=0}^{k-1}t\sum_{j=0}^{k-1}w_k^{ij}w_k^{-tj} \]

\[\frac 1 k\sum_{j=0}^{k-1}\sum_{t=0}^{k-1}tw_k^{-tj}\sum_{i=0}^n\binom n i p^iw_k^{ij} \]

\[\frac 1 k\sum_{j=0}^{k-1}(pw_k^j+1)^n\sum_{t=0}^{k-1}tw_k^{-tj} \]

于是我们考虑怎么快速计算 \(\sum_{i=0}^{n-1}ik^i\)

这看上去很像等比数列,按照等比数列求和公式的推导对这玩意儿做一遍:

为了方便,先设这玩意儿为 \(f(n,k)\)

\[kf(n,k)-f(n,k)=\sum_{i=0}^{n-1}ik^{i+1}-\sum_{i=0}^{n-1}ik^i \]

\[\sum_{i=1}^n(i-1)k^i-\sum_{i=0}^{n-1}ik^i \]

\[(n-1)k^n-\sum_{i=1}^{n-1}k^i \]

\[(n-1)k^n-\frac {k^n-k} {k-1} \]

又因为带入的都是 \(k\) 次单位根,所以上式的 \(k^n=1\)。于是:

\[n-1+\frac {1-k}{k-1}=n \]

所以 \(f(n,k) =\frac n {k-1}\),注意要特判 \(f(n,1) = \frac {n(n-1)} 2\)
整理一下:

\[\frac 1 k \times ( np(p+1)^{n+1} - \frac 1 k\sum_{j=0}^{k-1}(pw_k^j+1)^nf(k,w_k^{-j}) ) \]

贴代码:

#include<cstdio>
const int M=1<<23|5,mod=998244353;
int n,p,k,ans,w[M];
inline int pow(int a,int b=mod-2){
	int ans=1;
	for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)ans=1ll*ans*a%mod;
	return ans;
}
inline int Add(const int&a,const int&b){
	return a+b>=mod?a+b-mod:a+b;
}
inline int f(const int&n,const int&k){
	if(k==1)return (1ll*n*(n-1)>>1)%mod;
	return 1ll*n*pow(k-1)%mod;
}
signed main(){
	int i;
	scanf("%d%d%d",&n,&p,&k);
	w[0]=1;w[1]=pow(3,(mod-1)/k);
	for(i=2;i<=k;++i)w[i]=1ll*w[i-1]*w[1]%mod;
	for(i=0;i<k;++i)ans=Add(ans,1ll*pow((1ll*p*w[i]+1)%mod,n)*f(k,w[k-i])%mod);
	ans=(1ll*n*p%mod*pow(p+1,n-1)%mod-1ll*ans*pow(k)%mod+mod)%mod;
	printf("%d",1ll*ans*pow(k)%mod);
}
posted @ 2022-01-10 15:46  Prean  阅读(27)  评论(0编辑  收藏  举报
var canShowAdsense=function(){return !!0};