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;
}
posted @ 2024-02-03 15:51  LIUIR  阅读(9)  评论(0编辑  收藏  举报