結果
問題 | No.767 配られたジャパリまん |
ユーザー | maspy |
提出日時 | 2020-05-10 00:07:31 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 406 ms / 2,000 ms |
コード長 | 2,652 bytes |
コンパイル時間 | 810 ms |
コンパイル使用メモリ | 76,312 KB |
実行使用メモリ | 27,908 KB |
最終ジャッジ日時 | 2024-07-06 08:04:18 |
合計ジャッジ時間 | 3,528 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 33 ms
21,068 KB |
testcase_01 | AC | 32 ms
19,908 KB |
testcase_02 | AC | 33 ms
20,936 KB |
testcase_03 | AC | 33 ms
20,296 KB |
testcase_04 | AC | 33 ms
20,548 KB |
testcase_05 | AC | 52 ms
21,064 KB |
testcase_06 | AC | 34 ms
20,296 KB |
testcase_07 | AC | 32 ms
20,168 KB |
testcase_08 | AC | 32 ms
20,300 KB |
testcase_09 | AC | 33 ms
20,168 KB |
testcase_10 | AC | 42 ms
21,708 KB |
testcase_11 | AC | 34 ms
20,292 KB |
testcase_12 | AC | 33 ms
20,552 KB |
testcase_13 | AC | 41 ms
20,420 KB |
testcase_14 | AC | 34 ms
20,556 KB |
testcase_15 | AC | 32 ms
20,040 KB |
testcase_16 | AC | 34 ms
20,680 KB |
testcase_17 | AC | 32 ms
20,680 KB |
testcase_18 | AC | 33 ms
21,196 KB |
testcase_19 | AC | 34 ms
20,420 KB |
testcase_20 | AC | 406 ms
27,908 KB |
ソースコード
#include <iostream> #include <vector> typedef long long ll; #define U 1050000 using namespace std; vector<int> I, X, Y; int H, W, N; int MOD = 1e8 + 7; ll dp[U]; ll fact[U]; ll fact_inv[U]; ll mpow(ll a, ll n) { if (n == 0) { return 1; } ll x = mpow(a, n / 2); x = x * x % MOD; if (n & 1) { x = a * x % MOD; } return x; } void make_fact() { fact[0] = 1; for (int i = 1; i < U; i++) { fact[i] = i * fact[i - 1] % MOD; } fact_inv[U - 1] = mpow(fact[U - 1], MOD - 2); for (int i = U - 1; i > 0; i--) { fact_inv[i - 1] = fact_inv[i] * i % MOD; } } ll f(int S) { int x = 0; int y = 0; ll ret = 1; for (int r = 0; r < N; r++) { int i = I[r]; if (!(S & (1 << i))) { continue; } int x1 = X[r]; int y1 = Y[r]; int dx = x1 - x; int dy = y1 - y; if (dx < 0 || dy < 0) { return 0; } ret *= fact[dx + dy] * fact_inv[dx] % MOD * fact_inv[dy] % MOD; ret %= MOD; x = x1; y = y1; } int dx = H - x; int dy = W - y; ret *= fact[dx + dy] * fact_inv[dx] % MOD * fact_inv[dy] % MOD; return ret % MOD; } void mobius() { for (int i = 0; i < N; i++) { for (int n = 0; n < (1 << N); n++) { if (!(n & (1 << i))) { dp[n] -= dp[n ^ (1 << i)]; dp[n] %= MOD; continue; } } } } void zeta() { for (int i = 0; i < N; i++) { for (int n = 0; n < (1 << N); n++) { if (n & (1 << i)) { dp[n] += dp[n ^ (1 << i)]; dp[n] %= MOD; continue; } } } } int main() { make_fact(); cin >> H >> W >> N; for (int i = 0; i < N; i++) { int x, y; cin >> x >> y; I.push_back(i); X.push_back(x); Y.push_back(y); } // 雑ソート for (int i = 0; i < N * N; i++) { for (int j = 0; j < N - 1; j++) { if (X[j] + Y[j] > X[j + 1] + Y[j + 1]) { swap(I[j], I[j + 1]); swap(X[j], X[j + 1]); swap(Y[j], Y[j + 1]); } } } for (int i = 0; i < (1 << N); i++) { dp[i] = f(i); } mobius(); zeta(); for (int i = (1 << N) - 1; i >= 0; i--) { ll x = dp[i]; if (x < 0) { x += MOD; } cout << x << "\n"; } return 0; }