結果

問題 No.1321 塗るめた
ユーザー 37zigen
提出日時 2020-12-18 03:49:22
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
TLE  
(最新)
AC  
(最初)
実行時間 -
コード長 5,919 bytes
コンパイル時間 1,723 ms
コンパイル使用メモリ 110,172 KB
最終ジャッジ日時 2025-01-17 02:42:41
ジャッジサーバーID
(参考情報)
judge3 / judge4
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 44 TLE * 1
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#include <string>
#include <iostream>
#include <vector>
#include <cassert>
#include <random>
constexpr long long p = 998244353;
long long ADD(long long a, long long b) {
return a + b >= p ? a + b - p : a + b;
}
std::vector<long long> trim(std::vector<long long> a, int n) {
std::vector<long long> b(n, 0);
for (int i = 0; i < std::min(n, (int) a.size()); ++i) b[i] = a[i];
return b;
}
std::vector<long long> shift(std::vector<long long> a, int shift) {
std::vector<long long> b(a.size(), 0);
for (int i = 0; i < (int) a.size(); ++i) b[i] = (0 <= i - shift && i - shift < (int) a.size()) ? a[i - shift] : 0;
return b;
}
long long pow_mod(long long a, long long n) {
return n == 0 ? 1 : (pow_mod(a * a % p, n / 2) * (n % 2 == 1 ? a : 1)) % p;
}
long long modinv(long long a) {
return pow_mod(a, p - 2);
}
std::vector<long long> add(std::vector<long long> a, std::vector<long long> b) {
int n = std::max(a.size(), b.size());
std::vector<long long> c(n);
a.resize(n);
b.resize(n);
for (int i = 0; i < n; ++i) c[i] = ADD(a[i], b[i]);
return c;
}
std::vector<long long> subtract(std::vector<long long> a, std::vector<long long> b) {
int n = std::max(a.size(), b.size());
std::vector<long long> c(n);
a.resize(n);
b.resize(n);
for (int i = 0; i < n; ++i) c[i] = ADD(a[i], p - b[i]);
return c;
}
void fft(std::vector<long long> &a, long long g) {
int n = a.size();
g = pow_mod(g, (p - 1) / n);
{
int i = 0;
for (int j = 0; j < n; ++j) {
if (i > j) std::swap(a[i], a[j]);
for (int k = n / 2; k > (i ^= k); k /= 2);
}
}
for (int len = 1; len <= n / 2; len *= 2) {
long mul = pow_mod(g, n / (2 * len));
for (int src = 0; src < n; src += 2 * len) {
long long x = 1;
for (int pos = src; pos < src + len; ++pos) {
long long A = a[pos];
long long B = a[pos + len] * x % p;
a[pos] = ADD(A, B);
a[pos + len] = ADD(A, p - B);
x = x * mul % p;
}
}
}
}
std::vector<long long> mul(std::vector<long long> a, std::vector<long long> b) {
long long g = 3;
int n = 1;
while (n < (int) (a.size() + b.size() - 1)) n *= 2;
a.resize(n);
b.resize(n);
fft(a, g);
fft(b, g);
long long inv_n = modinv(n);
for (int i = 0; i < n; ++i) a[i] = a[i] * b[i] % p * inv_n % p;
fft(a, modinv(g));
return a;
}
std::vector<long long> mul(std::vector<long long> a, long long b) {
int n = a.size();
std::vector<long long> c(n);
for (int i = 0; i < n; ++i) c[i] = a[i] * b % p;
return c;
}
std::vector<long long> finv(std::vector<long long> a) {
int n = a.size();
std::vector<long long> b = {modinv(a[0])};
for (int len = 1; len < n; len *= 2) {
b = subtract(mul(b, 2), trim(mul(mul(b, b), trim(a, 2 * len)), 2 * len));
}
return b;
}
std::vector<long long> differentiate(std::vector<long long> a) {
int n = a.size();
for (int i = 0; i + 1 < n; ++i) a[i] = (i + 1) * a[i + 1] % p;
a[n - 1] = 0;
return a;
}
std::vector<long long> integrate(std::vector<long long> a) {
for (int i = a.size() - 1; i >= 1; --i) a[i] = modinv(i) * a[i - 1] % p;
a[0] = 0;
return a;
}
std::vector<long long> log(std::vector<long long> a) {
assert(a[0] == 1);
return integrate(mul(differentiate(a), finv(a)));
}
std::vector<long long> exp(std::vector<long long> a) {
assert(a[0] == 0);
int n = a.size();
std::vector<long long> b = {1};
for (int len = 1; len < n; len *= 2) {
std::vector<long long> tmp = subtract(trim(a, 2 * len), log(trim(b, 2 * len)));
++tmp[0];
b = trim(mul(b, tmp), 2 * len);
}
return b;
}
std::vector<long long> pow(std::vector<long long> a, int n) {
assert(n >= 1);
int s = 0;
while (s < (int) a.size() && a[s] == 0) ++s;
if (s == (int) a.size()) return a;
a = shift(a, -s);
long long b = modinv(a[0]);
for (int i = 0; i < (int) a.size(); ++i) a[i] = b * a[i] % p;
a = log(a);
for (int i = 0; i < (int) a.size(); ++i) a[i] = n % p * a[i] % p;
a = exp(a);
b = pow_mod(modinv(b), n % (p - 1));
for (int i = 0; i < (int) a.size(); ++i) a[i] = b * a[i] % p;
a = shift(a, s * n);
return a;
}
std::vector<long long> pow_exact(std::vector<long long> a, int n) {
std::vector<long long> b = {1};
for (int i = 0; i < n; ++i) b = trim(mul(b, a), a.size());
return b;
}
void verify() {
std::random_device seed_gen;
std::mt19937_64 engine(seed_gen());
for (int t = 0; t < 100000; ++t) {
int n = engine() % 100 + 1;
int k = engine() % 100 + 1;;
std::vector<long long> a(n);
for (int i = 0; i < n; ++i) a[i] = engine() % p;
std::vector<long long> u = pow(a, k);
std::vector<long long> v = pow_exact(a, k);
for (int i = 0; i < n; ++i) {
assert(u[i] == v[i]);
}
std::cout << "case" << t << ":passed" << std::endl;
}
}
const int MAX = (int) 2e5;
long long fac[MAX];
long long ifac[MAX];
long long inv[MAX];
long long comb(int n, int k) {
return fac[n] * ifac[n - k] % p * ifac[k] % p;
}
int main() {
int N, M, K;
std::cin >> N >> M >> K;
fac[0] = fac[1] = ifac[0] = ifac[1] = inv[0] = inv[1] = 1;
for (int i = 2; i < MAX; ++i) {
fac[i] = i * fac[i - 1] % p;
inv[i] = p - inv[p % i] * (p / i) % p;
ifac[i] = inv[i] * ifac[i - 1] % p;
}
std::vector<long long> f((int) 1e5 + 10);
for (int i = 0; i < f.size(); ++i) f[i] = ifac[i];
f[0] = 0;
f = pow(f, K);
long long ans = 0;
for (int i = K; i <= N; ++i) {
ans += comb(N, i) * comb(M, K) % p * pow_mod(M, N - i) % p * f[i] % p * fac[i] % p;
ans %= p;
}
std::cout << ans << std::endl;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0