CF1278F Cards 加强版
题解区没有 Binomial Sum 的做法,我来写一篇题解。
为了让文章短一点,我删去了部分过程,如果对推导过程有问题或指出错误可以私信我 qwq。
假设读者已经做过了原题,于是有:
对于类二项式定理的题目,
对于
还有就是利用
回代原式,有:
为方便,设
设
于是可以令
求 h
对
还有
最后是
然后没了。
代码丑:
#include <bits/stdc++.h>
const int mod = 998244353;
using namespace std;
int fac[10000015], ifac[10000015], id[10000015];
int pri[10000015], cnt;
bool vis[10000015];
int dn[10000015];
int fpow(int a, int b = mod - 2)
{
int r = 1;
while (b)
{
if (b & 1)
r = 1LL * r * a % mod;
a = 1LL * a * a % mod;
b >>= 1;
}
return r;
}
void init(int n, int k)
{
fac[0] = ifac[0] = fac[1] = ifac[1] = id[1] = 1;
for (int i = 2; i <= n; i++)
{
fac[i] = 1LL * fac[i - 1] * i % mod;
if (!vis[i])
{
pri[++cnt] = i;
id[i] = fpow(i, k);
}
for (int j = 1; j <= cnt; j++)
{
if (1LL * i * pri[j] >= n)
break;
vis[i * pri[j]] = 1;
id[i * pri[j]] = 1LL * id[i] * id[pri[j]] % mod;
if (i % pri[j] == 0)
{
break;
}
}
}
ifac[n] = fpow(fac[n]);
for (int i = n - 1; i >= 2; i--)
ifac[i] = 1LL * ifac[i + 1] * (i + 1) % mod;
}
inline int C(int n, int m)
{
if (n < m || m < 0)
return 0;
return 1LL * fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}
inline int inv(int n)
{
return 1LL * fac[n - 1] * ifac[n] % mod;
}
int n, m, k, q;
inline int Cn(int m)
{
if (n < m || m < 0)
return 0;
return 1LL * dn[m] * ifac[m] % mod;
}
int f,fk1;
inline int d(int i)
{
int res = 1LL * (1 + q) * (k + 1) % mod * fk1 % mod * C(k, i) % mod;
if ((k - i) & 1)
res = (mod - res) % mod;
return res;
}
signed main()
{
cin >> n >> m >> k;
if (m == 1)
{
cout << fpow(n, k);
return 0;
}
init(k + 10, k);
int ans = 0;
q = fpow(m - 1);
dn[0] = 1;
for (int i = 1; i <= k + 1; i++)
dn[i] = 1LL * dn[i - 1] * (n - i + 1) % mod;
if (n <= k + 10)
{
int lk = 1LL * fpow(m - 1, n) % mod * fpow(fpow(m, n)) % mod;
int inv = fpow(m - 1);
for (int i = 0; i <= n; i++)
{
ans = (ans + 1LL * C(n, i) * lk % mod * id[i] % mod) % mod;
lk = 1LL * lk * inv % mod;
}
cout << ans;
return 0;
}
fk1 = 1LL * Cn(k + 1) * fpow(q, k + 1) % mod * fpow(q + 1, n - k - 1) % mod;
int t1 = 1, t2 = 1, nd = fpow(1 + q);
for (int i = 0; i <= k; i++)
{
int tmp = 1LL * t1 * Cn(i) % mod * t2 % mod;
if (i & 1)
tmp = (mod - tmp) % mod;
f = (f + tmp) % mod;
t1 = 1LL * t1 * q % mod;
t2 = 1LL * t2 * nd % mod;
}
f = 1LL * f * fpow(1 + q, n) % mod;
for (int i = 1; i <= k; i++)
{
f = (1LL * (n - i + 1) * q % mod * f % mod - d(i - 1) + mod) % mod;
f = 1LL * f * inv(i) % mod;
ans = (ans + 1LL * f * id[i] % mod) % mod;
}
ans = 1LL * ans * fpow(1LL * (m - 1) * fpow(m) % mod, n) % mod;
cout << ans;
return 0;
}