結果

問題 No.2983 Christmas Color Grid (Advent Calender ver.)
ユーザー Kude
提出日時 2024-12-08 02:11:42
言語 C++23
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 748 ms / 3,340 ms
コード長 4,641 bytes
コンパイル時間 3,630 ms
コンパイル使用メモリ 279,392 KB
実行使用メモリ 5,248 KB
最終ジャッジ日時 2024-12-08 02:11:52
合計ジャッジ時間 9,338 ms
ジャッジサーバーID
(参考情報)
judge5 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 64
権限があれば一括ダウンロードができます

ソースコード

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

#include<bits/stdc++.h>
namespace {
#pragma GCC diagnostic ignored "-Wunused-function"
#include<atcoder/all>
#pragma GCC diagnostic warning "-Wunused-function"
using namespace std;
using namespace atcoder;
#define rep(i,n) for(int i = 0; i < (int)(n); i++)
#define rrep(i,n) for(int i = (int)(n) - 1; i >= 0; i--)
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
template<class T> bool chmax(T& a, const T& b) { if (a < b) { a = b; return true; } else return false; }
template<class T> bool chmin(T& a, const T& b) { if (b < a) { a = b; return true; } else return false; }
using ll = long long;
using P = pair<int,int>;
using VI = vector<int>;
using VVI = vector<VI>;
using VL = vector<ll>;
using VVL = vector<VL>;
using mint = modint;
const int di[] = {1, 0, -1, 0};
const int dj[] = {0, 1, 0, -1};
mint comb[30][30], fact[30], inv[30], pow2[30];
} int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int h, w, m;
ll k;
cin >> h >> w >> k >> m;
mint::set_mod(m);
comb[0][0] = 1;
rep(i, 29) rep(j, i + 1) comb[i+1][j] += comb[i][j], comb[i+1][j+1] += comb[i][j];
fact[0] = pow2[0] = 1;
for (int i = 1; i < 30; i++) fact[i] = fact[i-1] * i, inv[i] = mint(i).inv(), pow2[i] = pow2[i-1] * 2;
vector<tuple<int, int, int>> st;
bool seen[25][25]{};
int dist[26][26]{};
rep(i0, h) rep(j0, w) {
auto dfs = [&](auto&& self, int use, int unuse) -> void {
if (st.empty()) {
dist[use][unuse]++;
return;
}
auto [i, j, k] = st.back(); st.pop_back();
if (k < 4) {
int ni = i + di[k], nj = j + dj[k];
st.emplace_back(i, j, k + 1);
if (0 <= ni && ni < h && 0 <= nj && nj < w && !seen[ni][nj]) {
if (pair(i0, j0) < pair(ni, nj)) {
st.emplace_back(ni, nj, 0);
seen[ni][nj] = true;
self(self, use + 1, unuse);
seen[ni][nj] = false;
st.pop_back();
}
seen[ni][nj] = true;
self(self, use, unuse + 1);
seen[ni][nj] = false;
} else {
self(self, use, unuse);
}
st.pop_back();
} else {
self(self, use, unuse);
}
st.emplace_back(i, j, k);
};
st.emplace_back(i0, j0, 0);
seen[i0][j0] = true;
dfs(dfs, 1, 0);
seen[i0][j0] = false;
assert(st.size() == 1);
st.pop_back();
}
mint ans;
rep(use, 26) rep(unuse, 26) if (dist[use][unuse]) ans += mint(use).pow(k) * dist[use][unuse] * pow2[h * w - use - unuse];
ans /= pow2[h * w];
mint c;
for (int i = 1; i <= h * w; i++) c += inv[i];
ans *= c;
cout << ans.val() << '\n';
exit(0);
rep(use, 26) {
mint cnt;
rep(unuse, 26) if (dist[use][unuse]) for (int chose = use; chose <= h * w; chose++) {
// cout << use << ' '<< unuse << endl;
int free_area = h * w - use - unuse;
int rest = chose - use;
for (int cf = 0; cf <= rest; cf++) {
int cu = rest - cf;
if (cf <= free_area && cu <= unuse) {
cnt += dist[use][unuse] * comb[free_area][cf] * pow2[cf] * comb[unuse][cu] * fact[chose] * fact[h * w - chose] * inv[h * w - chose + 1];
}
}
}
if (cnt.val()) cout << use << ' ' << cnt.val() << endl;
ans += cnt * mint(use).pow(k);
}
ans /= fact[h * w] * mint(2).pow(h * w);
cout << ans.val() << '\n';
// int acc = 0;
// rep(i, 26) rep(j, 26) acc += dist[i][j];
// cout << acc << endl;
// for (int h = 1; h <= 25; h++) {
// for (int w = h; h * w <= 25; w++) {
// int valid_cnt = 0;
// bool g[25][25];
// vector<P> st;
// int dist[26]{};
// rep(s, 1 << h * w) if (s) {
// rep(i, h) rep(j, w) g[i][j] = s >> i * w + j & 1;
// int sv = countr_zero(0U + s);
// int i0 = sv / w, j0 = sv % w;
// st.emplace_back(i0, j0);
// g[i0][j0] = 0;
// while (st.size()) {
// auto [i, j] = st.back(); st.pop_back();
// auto idxchk = [&](int i, int j) { return 0 <= i && i < h && 0 <= j && j < w; };
// rep(k, 4) {
// int ni = i + di[k], nj = j + dj[k];
// if (!idxchk(ni, nj) || !g[ni][nj]) continue;
// g[ni][nj] = 0;
// st.emplace_back(ni, nj);
// }
// }
// if ([&]() {
// rep(i, h) rep(j, w) if (g[i][j]) return false;
// return true;
// }()) {
// dist[popcount(0U + s)]++;
// }
// }
// // cout << '{';
// // rep(i, 26) cout << dist[i] << ",}"[i == 25];
// // cout << ',';
// cout << h << ' ' << w << ' ' << accumulate(all(dist), 0) << endl;
// }
// }
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0