luogu P5591 小猪佩奇学数学题解
luogu P5591 小猪佩奇学数学题解
题目大意
给定 \(n,p,k\),求
\[\sum_{i=0}^k\binom{n}{i}\times p^i\times\lfloor\frac{i}{k}\rfloor\bmod998244353
\]
\(1\le n,p<998244353\),\(k\in{2^w|0\le w\le20}\)。
题目分析
先将 \(\lfloor\frac{i}{k}\rfloor\) 拆为 \(\frac{i-i\bmod k}{k}\),得
\[\sum_{i=0}^n\binom{n}{i}\times p^i\times\frac{i-i\bmod k}{k}
\]
略去 \(\frac{1}{k}\),并将括号拆开分别考虑。
-
前半部分:
\[\sum_{i=0}^n\binom{n}{i}\times p^i\times i \]根据 \(\dbinom{n}{m}=\dfrac{n}{m}\dbinom{n-1}{m-1}\) 可得
\[np\sum_{i=0}^n\binom{n-1}{i-1}\times p^{i-1}\times1^{n-i} \]即
\[np(p+1)^{n-1} \] -
后半部分:
\[\sum_{i=0}^n\binom{n}{i}\times p^i\times(i\bmod k) \]我们可以将 \(i\bmod k\) 看作 \(\sum_{j=0}^{k-1}j[i\equiv j\pmod k]\),然后用单位根反演得 \(\sum_{j=0}^{k-1}\frac{j}{k}\sum_{t=0}^{k-1}\omega_k^{(i-j)t}\),即有
\[\sum_{i=0}^n\binom{n}{i}\times p^i\sum_{j=0}^{k-1}\frac{j}{k}\sum_{t=0}^{k-1}\omega_k^{(i-j)t} \]更改求和符号顺序可得
\[\frac{1}{k}\sum_{j=0}^{k-1}j\sum_{t=0}^{k-1}\omega_k^{-jt}\sum_{i=0}^n\binom{n}{i}\times(p\omega_k^t)^i\times1^{n-i} \]根据二项式定理可得
\[\frac{1}{k}\sum_{j=0}^{k-1}j\sum_{t=0}^{k-1}\omega_k^{-jt}(p\omega_k^t+1)^n \]再次更改求和符号顺序可得
\[\frac{1}{k}\sum_{t=0}^{k-1}(p\omega_k^t+1)^n\sum_{j=0}^{n-1}j\omega_k^{-jt} \]若设 \(f(x)\) 表示 \(\sum_{i=0}^{n-1}ix^i\),则有
\[\frac{1}{k}\sum_{t=0}^{k-1}(p\omega_k^t+1)^nf(\omega_k^{-t}) \]接下来考虑如何求 \(f(x)\)。
-
当 \(x\not=1\) 时,求 \(xf(x)-f(x)\),有
\[\begin{aligned} xf(x)-f(x)&=(n-1)x^n-\sum_{i=1}^{n-1}x^i\\ &=1+(n-1)x^n-\sum_{i=0}^{n-1}x^i\\ &=1+(n-1)x^n-\frac{x^n-1}{x-1}\\ \end{aligned} \]因为 \(x=\omega_n^{-t}\),所以 \(x^n=1\),则有
\[xf(x)-f(x)=n \]所以有
\[f(x)=\frac{n}{x-1} \] -
而当 \(x=1\) 时,\(f(x)=\dfrac{k(k-1)}2\)。
因此可以直接计算。
-
代码
//Author:LIUIR
//2024.02.03
//Start coding:14:46:22
//Finish debgging:15:04:08
#include <bits/stdc++.h>
#define int long long
const int MOD = 998244353;
const int INV2 = 499122177;
int n, p, k, w, ans, sum, invk;
int Pow(int, int);
signed main()
{
scanf("%lld%lld%lld", &n, &p, &k);
invk = Pow(k, MOD - 2);
w = Pow(3, (MOD - 1) / k);
ans = n * p % MOD * Pow(p + 1, n - 1) % MOD;
for (int i = 0; i < k; i++)
{
int c = Pow(w, MOD - i - 1), val;
if (c != 1)
val = k * Pow(c - 1, MOD - 2) % MOD;
else
val = k * (k - 1) % MOD * INV2 % MOD;
sum = (sum + Pow(p * Pow(w, i) % MOD + 1, n) * val % MOD) % MOD;
}
sum = sum * invk % MOD;
printf("%lld", (ans - sum + MOD) % MOD * invk % MOD);
return 0;
}
int Pow(int x, int y)
{
int res = 1;
for (; y; x = x * x % MOD, y >>= 1)if (y & 1)
res = res * x % MOD;
return res;
}