結果
問題 |
No.3285 Chorus with Friends
|
ユーザー |
|
提出日時 | 2025-09-26 22:57:51 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 4,292 bytes |
コンパイル時間 | 4,579 ms |
コンパイル使用メモリ | 269,132 KB |
実行使用メモリ | 7,720 KB |
最終ジャッジ日時 | 2025-09-26 22:57:58 |
合計ジャッジ時間 | 6,143 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 WA * 2 |
other | AC * 15 WA * 25 |
ソースコード
#include <bits/stdc++.h> #include <atcoder/all> using namespace std; using isize = size_t; using i32 = int; using u32 = unsigned int; using i64 = long long; using u64 = unsigned long long; using i128 = __int128_t; using u128 = __uint128_t; using f64 = long double; using p2 = pair<i64, i64>; using el = tuple<i64, i64, i64>; using mint = atcoder::modint998244353; void _main(); int main() { cin.tie(0); ios::sync_with_stdio(false); cout << fixed << setprecision(18); _main(); } i64 pow(i64 x, i64 n) { i64 res = 1; i64 t = x; while (n > 0) { if (n & 1) res *= t; t *= t; n >>= 1; } return res; } i64 pow(i64 x, i64 n, i64 m) { i64 res = 1; i64 t = x % m; while (n > 0) { if (n & 1) res = res * t % m; t = t * t % m; n >>= 1; } return res; } i64 N; vector<vector<mint>> ranked_zeta(vector<mint> a) { vector<vector<mint>> res(1 << N, vector<mint>(N + 1, 0)); for (i64 i = 0; i < 1 << N; i++) { res[i][__builtin_popcountll(i)] = a[i]; } for (i64 i = 0; i < N; i++) { for (i64 j = 0; j < 1 << N; j++) { for (i64 k = 0; k <= N; k++) { if (!(j >> i & 1)) continue; res[j][k] += res[j - (1 << i)][k]; } } } return res; } vector<mint> ranked_mobius(vector<vector<mint>> a) { vector<mint> res(1 << N, 0); for (i64 i = 0; i < N; i++) { for (i64 j = 0; j < 1 << N; j++) { for (i64 k = 0; k <= N; k++) { if (!(j >> i & 1)) continue; a[j][k] -= a[j - (1 << i)][k]; } } } for (i64 i = 0; i < 1 << N; i++) { res[i] = a[i][__builtin_popcountll(i)]; } return res; } vector<mint> subset_convolution(vector<mint> &a, vector<mint> &b) { vector<vector<mint>> u = ranked_zeta(a); vector<vector<mint>> v = ranked_zeta(b); vector<vector<mint>> s(1 << N, vector<mint>(N + 1, 0)); for (i64 i = 0; i < 1 << N; i++) { for (i64 j = 0; j <= N; j++) { for (i64 k = 0; j + k <= N; k++) { s[i][j + k] += u[i][j] * v[i][k]; } } } return ranked_mobius(s); } void _main() { i64 n, m; cin >> n >> m; vector<vector<i64>> a(n, vector<i64>(m)); for (i64 i = 0; i < n; i++) { for (i64 j = 0; j < m; j++) { cin >> a[i][j]; } } vector<i64> col; for (i64 i = 0; i < n; i++) col.push_back(a[i][0]); sort(col.begin(), col.end()); col.erase(unique(col.begin(), col.end()), col.end()); mint ans = 0; if (n < m) { for (i64 x : col) { vector<vector<bool>> s(n, vector<bool>(m)); vector<i64> v; for (i64 i = 0; i < n; i++) { for (i64 j = 0; j < m; j++) { s[i][j] = x == a[i][j]; } if (s[i][0]) v.push_back(i); } vector<mint> dp(1 << v.size(), 0); dp[(1 << v.size()) - 1] = 1; for (i64 k = 1; k <= m; k++) { vector<mint> ndp(1 << v.size(), 0); for (i64 i = 0; i < 1 << v.size(); i++) { for (i64 j = 0; j < v.size(); j++) { if (!(i >> j & 1)) continue; if (k == m) { ans += dp[i]; continue; } if (s[j][k]) { ndp[i] += dp[i]; } else { ndp[i ^ (1 << j)] += dp[i]; } } } swap(dp, ndp); } } } else { return; for (i64 x : col) { vector<vector<bool>> s(n, vector<bool>(m)); vector<i64> v; for (i64 i = 0; i < n; i++) { for (i64 j = 0; j < m; j++) { s[i][j] = x == a[i][j]; } if (s[i][0]) v.push_back(i); } vector<mint> dp(1 << m, 0); dp[0] = 1; for (i64 i : v) { vector<i64> u; for (i64 j = 0; j < m; j++) if (s[i][j]) u.push_back(j); vector<mint> ndp(1 << n, 0); N = m; for (i64 j = 0; j < 1 << n; j++) { bool ok = true; i64 mx = -1; for (i64 k = 0; k < n; k++) { if (j >> k & 1) { mx = k; } } for (i64 k = 0; k < n; k++) { if (k == mx) continue; if (j >> k & 1) { ok &= s[i][k + 1]; } } if (!ok) continue; ndp[j] = 1; } dp = subset_convolution(dp, ndp); } ans += dp[(1 << m) - 1]; } } cout << ans.val() << "\n"; }