結果
問題 | No.2409 Strange Werewolves |
ユーザー |
|
提出日時 | 2023-08-11 22:30:45 |
言語 | D (dmd 2.109.1) |
結果 |
AC
|
実行時間 | 202 ms / 2,000 ms |
コード長 | 1,941 bytes |
コンパイル時間 | 4,147 ms |
コンパイル使用メモリ | 173,596 KB |
実行使用メモリ | 9,440 KB |
最終ジャッジ日時 | 2024-11-18 17:12:16 |
合計ジャッジ時間 | 6,532 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 16 |
ソースコード
import std;void main () {int X, Y, Z, W; readln.read(X, Y, Z, W);solve(X, Y, Z, W);}void solve (int X, int Y, int Z, int W) {// 片方が追放されるとして、これは片方の順列にもう片方の元を好きなように差し込む通り数になる?const int MOD = 998244353;long ans = 1;// 常に人間側が残るように正規化if (Z == 0) {swap(X, Y);swap(Z, W);}for (int i = 1; i <= Y; i++) {ans *= i;ans %= MOD;}long[] fac = new long[](X+1);long[] fac_inv = new long[](X+1);fac[0] = fac_inv[0] = 1;foreach (i; 1..X+1) {fac[i] = i*fac[i-1];fac[i] %= MOD;fac_inv[i] = modPow(fac[i], MOD-2, MOD);}long nCk (long n, long k) {long res = fac[n];res *= fac_inv[k];res %= MOD;res *= fac_inv[n-k];return res % MOD;}// X-Z人を選ぶところからなので、X C X-Z を計算しないといけないans *= nCk(X, X-Z);ans %= MOD;for (int i = 0; i < X-Z; i++) {// i人目はY+i-1人の(右端を除く)隙間に入る感じans *= Y+i;ans %= MOD;}writeln(ans);}void read(T...)(string S, ref T args) {auto buf = S.split;foreach (i, ref arg; args) {arg = buf[i].to!(typeof(arg));}}long modPow (long a, long x, const int MOD) {// assertionassert(0 <= x);assert(1 <= MOD);// normalizea %= MOD; a += MOD; a %= MOD;// simple caseif (MOD == 1) {return 0L;}if (x == 0) {return 1L;}if (x == 1) {return a;}// calculatelong res = 1L;long base = a % MOD;while (x != 0) {if ((x&1) != 0) {res *= base;res %= MOD;}base = base*base; base %= MOD;x >>= 1;}return res;}