LOJ[6247]九个太阳
题面:
在遥远的苏远山上,yww 自诩为太阳。
yww 对其他自以为是太阳的人很敌视,他决定通过发出光芒来教化这些人。当 yww 的光芒照耀到一个人的身上时,这个人就会在这股古老而强大的力量的压迫下,双膝跪地,双手平举,随后身体前俯后仰,手也跟着摆动,并大声喊道:「yww 是我们的红太阳!」。
除了 yww 以外,苏远山上一共有 nn 个自以为是太阳的人。由于 yww 具有某种神秘力量,一次教化的人数只能是正整数 KK 的倍数,且 KK 是 22 的幂。
yww 想知道,如果他发出光芒,被教化的人有多少种情况。两种情况视作不同,当且仅当存在一个人,在一种情况中被教化,在另外一种情况中没有被教化。由于情况实在太多了,所以答案为 998244353取模。
一句话题意:给定n,k,保证k是2的整数幂,求$\sum_{k|i,0\leq i\leq n}\binom{n}{i}$,对 998244353取模。
在推导 FFT 的时候,我们有求和引理:$\begin{aligned} \frac{1}{n} \sum_{i = 0} ^ {n - 1} (w_n ^ x) ^ i = [x \equiv 0(\mod n)] \end{aligned}$
$\begin{aligned} \sum_{1 \le i \le n, K | i} \binom{n}{i} & = \sum_{i} [i \equiv 0(\mod K)] \binom{n}{i} \\ & = \sum_i \frac{1}{K} \sum_{j = 0} ^ {K - 1} (w_K ^ i) ^ j \binom{n}{i} \\ & = \frac{1}{K} \sum_{j = 0} ^ {K - 1} \sum_{i = 0} ^ n \binom{n}{i} (w_K ^ j) ^ i \\ & = \frac{1}{K} \sum_{j = 0} ^ {K - 1} (w_K ^ j + 1) ^ n \end{aligned}$
由于答案对 $998244353$ 取模,且 $K$ 是 $2$ 的幂,所以取模 $998244353$ 意义下的 $K$ 次单位根 $w_K = 3 ^ {\frac{P - 1}{K}}$ 。
#include <bits/stdc++.h> using namespace std; #define F(i, a, b) for (register int i = (a), _b = (b); i <= _b; i++) #define LL long long const int P = 998244353; inline int pw(int x, LL y) { int m = 1; for (; y > 0; y >>= 1, x = 1LL * x * x % P) if (y & 1) m = 1LL * m * x % P; return m; } inline int inv(int x) { return pw(x, P-2); } LL n; int K, ans; int main(void) { scanf("%lld %d", &n, &K); int wn = pw(3, (P-1) / K); for (int i = 0, c = 1; i < K; i++, c = 1LL * c * wn % P) ans = (ans + pw(c+1, n)) % P; ans = 1LL * ans * inv(K) % P; printf("%d\n", ans); return 0; }