Vexoben
Mar 12, 2019
题目链接:UO450 复读机J
(刷新以获取数学公式)
## 题意
群里有个不同的复读机。为了庆祝平安夜的到来,在接下来的秒内,它们每秒钟都会选出一位优秀的复读机进行复读。非常滑稽的是,一个复读机只有总共复读了的倍数次才会感到快乐。问有多少种不同的安排方式使得所有的复读机都感到快乐。
数据范围: 时 时
题解
显然答案就是
cly_none说这可以单位根反演一下。
(这个式子在FFT的时候用到过)所以原式就变成
大力化简一下就是
然后人工智慧对 分讨:
,答案就是
,答案是,二项式展开计算一下就是。
,答案是,多项式定理大力展开计算。
#include<bits/stdc++.h>
#define fi first
#define se second
#define R register
#define mp make_pair
#define pb push_back
#define LL long long
#define Ldb long double
#define pii pair<int, int>
using namespace std;
const int mod = 19491001;
template <typename T> void read(T &x) {
int f = 0;
R char c = getchar();
while (c < '0' || c > '9') f |= (c == '-'), c = getchar();
for (x = 0; c >= '0' && c <= '9'; c = getchar())
x = x * 10 - '0' + c;
if (f) x = -x;
}
int Qpow(int x, int p) {
if (x < 0) x += mod;
int ans = 1;
while (p) {
if (p & 1) ans = 1LL * ans * x % mod;
x = 1LL * x * x % mod;
p >>= 1;
}
return ans;
}
int Inv(int x) {
return Qpow(x, mod - 2);
}
// --------------------------------------------
int n, k, d;
int fac[mod], inv[mod], fav[mod];
void init() {
fac[0] = fav[0] = 1;
inv[1] = fac[1] = fav[1] = 1;
for (int i = 2; i < mod; ++i) {
inv[i] = 1LL * -mod / i * inv[mod % i] % mod + mod;
fac[i] = 1LL * fac[i - 1] * i % mod;
fav[i] = 1LL * fav[i - 1] * inv[i] % mod;
}
}
int C(int x, int y) {
return 1LL * fac[x] * fav[y] % mod * fav[x - y] % mod;
}
void Solver1() {
int ans = 0;
for (int i = 0; i <= k; ++i) {
LL tmp = 1LL * Qpow(2 * i - k, n) * C(k, i) % mod;
if (tmp < 0) tmp += mod;
ans = (ans + tmp) % mod;
}
ans = 1LL * ans * Qpow(inv[2], k) % mod;
cout << ans << endl;
}
void Solver2() {
int omega = Qpow(7, (mod - 1) / 3), ans = 0;
for (int i = 0; i <= k; ++i) {
for (int j = 0; i + j <= k; ++j) {
LL x = (i + 1LL * j * omega + 1LL * (k - i - j) * omega * omega) % mod;
LL c = 1LL * fac[k] * fav[i] % mod *
fav[j] % mod * fav[k - i - j] % mod;
LL tmp = 1LL * Qpow(x, n) * c % mod;
ans = (ans + tmp) % mod;
}
}
ans = 1LL * ans * Qpow(inv[3], k) % mod;
cout << ans << endl;
}
int main() {
read(n); read(k); read(d);
init();
if (d == 1) printf("%d\n", Qpow(k, n));
if (d == 2) Solver1();
if (d == 3) Solver2();
return 0;
}