結果
| 問題 |
No.2108 Red or Blue and Purple Tree
|
| ユーザー |
hitonanode
|
| 提出日時 | 2022-09-20 00:04:33 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,018 ms / 4,000 ms |
| コード長 | 2,404 bytes |
| コンパイル時間 | 10,109 ms |
| コンパイル使用メモリ | 313,168 KB |
| 実行使用メモリ | 76,552 KB |
| 最終ジャッジ日時 | 2024-12-22 02:57:28 |
| 合計ジャッジ時間 | 21,401 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 7 |
ソースコード
// Validator
#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
using namespace std;
#include "testlib.h"
#include <atcoder/modint>
#include <atcoder/convolution>
using mint = atcoder::modint998244353;
template <typename modint> struct acl_fac {
std::vector<modint> facs, facinvs;
acl_fac(int N) {
assert(-1 <= N and N < modint::mod());
facs.resize(N + 1, 1);
for (int i = 1; i <= N; i++) facs[i] = facs[i - 1] * i;
facinvs.assign(N + 1, facs.back().inv());
for (int i = N; i > 0; i--) facinvs[i - 1] = facinvs[i] * i;
}
modint operator[](int i) const { return facs.at(i); }
modint finv(int i) const { return facinvs.at(i); }
};
constexpr int max_n = 2000;
acl_fac<mint> fac(max_n);
int main(int argc, char *argv[]) {
registerValidation(argc, argv);
vector<mint> f(max_n + 1);
for (int n = 1; n <= max_n; ++n) {
f.at(n) = (n == 1 ? 1 : mint(n).pow(n - 2)) * n * n * fac.finv(n);
}
vector<vector<mint>> dp(max_n + 1);
dp.at(0) = vector<mint>(max_n + 1);
dp.at(0).at(0) = 1;
for (int k = 1; k <= max_n; ++k) {
dp.at(k) = atcoder::convolution(f, dp.at(k - 1));
dp.at(k).resize(max_n + 1);
}
for (int k = 1; k <= max_n; ++k) {
for (int n = k; n <= max_n; ++n) {
if (k > 1) {
dp.at(k).at(n) *= fac[n] * fac.finv(k) * mint(n).pow(2 * (k - 2));
} else {
dp.at(k).at(n) = (n > 1 ? mint(n).pow(n - 2) : 1);
}
}
}
vector<vector<mint>> answers(1);
for (int n = 1; n <= max_n; ++n) {
vector<mint> g(n);
for (int i = 0; i < n; ++i) g.at(i) = dp.at(n - i).at(n) * fac[i] * (i % 2 ? -1 : 1);
vector<mint> fac_trans(n);
for (int i = 0; i < n; ++i) fac_trans.at(i) = fac.finv(i);
reverse(g.begin(), g.end());
g = atcoder::convolution(g, fac_trans);
g.resize(n);
reverse(g.begin(), g.end());
for (int i = 0; i < n; ++i) g.at(i) *= fac.finv(i) * (i % 2 ? -1 : 1);
answers.push_back(g);
}
int T = inf.readInt(1, 500000);
inf.readEoln();
while (T--) {
const int n = inf.readInt(2, max_n);
inf.readSpace();
const int k = inf.readInt(0, n - 1);
inf.readEoln();
cout << answers.at(n).at(k).val() << '\n';
}
inf.readEof();
}
hitonanode