Submission #1217432

#TimeUsernameProblemLanguageResultExecution timeMemory
1217432duckindogSolitaire (JOI16_solitaire)C++20
100 / 100
96 ms34888 KiB
#include <bits/stdc++.h> using namespace std; const int N = 2000 + 10, M = 1'000'000'007; int n; int a[4][N]; inline void add(auto& x, const auto& y) { x += y; if (x >= M) x -= M; } inline int powder(int a, int b) { int ret = 1; for (; b; b /= 2, a = 1ll * a * a % M) { if (b & 1) ret = 1ll * ret * a % M; } return ret; } inline int distribute(int n, int m) { int ret = 1; for (int i = 1; i <= n; ++i, ++m) ret = 1ll * ret * m % M; return ret; } int f[N][N * 3][2], prefDP[N * 3][2]; int pref[N], cnt[N]; int32_t main() { cin.tie(0)->sync_with_stdio(0); cin >> n; for (int i = 1; i <= 3; ++i) { for (int j = 1; j <= n; ++j) { char ch; cin >> ch; a[i][j] = (ch == 'x'); } } { // check can form answer bool isValid = true; if (a[1][1] || a[1][n] || a[3][1] || a[3][n]) isValid = false; for (int i = 1; i <= 3; i += 2) { int cnt0 = 0; for (int j = 1; j <= n; ++j) { if (a[i][j]) cnt0 += 1; else cnt0 = 0; if (cnt0 >= 2) isValid = false; } } if (!isValid) { cout << 0 << "\n"; return 0; } } for (int i = 1; i <= n; ++i) { cnt[i] = a[1][i] + a[3][i]; pref[i] = pref[i - 1] + a[1][i] + a[2][i] + a[3][i]; } for (int j = 0; j <= pref[1]; ++j) { if (a[2][1]) { if (j > cnt[1]) f[1][j][0] = (cnt[1] <= 1 ? 1 : 2); } else { if (!j) f[1][j][0] = (cnt[1] <= 1 ? 1 : 2); } } const int m = pref[n]; for (int i = 2; i <= n; ++i) { prefDP[0][0] = f[i - 1][0][0]; prefDP[0][1] = f[i - 1][0][1]; for (int j = 1; j <= m; ++j) { prefDP[j][0] = (prefDP[j - 1][0] + f[i - 1][j][0]) % M; prefDP[j][1] = (prefDP[j - 1][1] + f[i - 1][j][1]) % M; } auto getDP = [&](int l, int r, int type) { return !l ? prefDP[r][type] : (prefDP[r][type] - prefDP[l - 1][type] + M) % M; }; if (a[2][i]) { for (int j = 1; j <= pref[i]; ++j) { if (j >= cnt[i]) { // up & down and previous is 0 auto& ret = f[i][j][0]; int value = 1ll * getDP(0, m, 0) * distribute(cnt[i], j - cnt[i]) % M; add(ret, value); } if (j >= cnt[i]) { // up & down and previous is 1 auto& ret = f[i][j][0]; int value = 1ll * getDP(j - cnt[i], m, 1) * distribute(cnt[i], j - cnt[i]) % M; add(ret, value); } { // left & right auto& ret = f[i][j][1]; for (int k = 0; k < cnt[i] && k < j; ++k) { int value = 1ll * getDP(0, j - 1 - k, 0) * distribute(k, j - k) % M * distribute(cnt[i] - k, pref[i - 1] + 2 - (j - k)) % M; if (k) value = 1ll * value * max(1, cnt[i]) % M; add(ret, value); } } } } else { auto& ret = f[i][0][0]; int value = 1ll * (getDP(0, m, 0) + getDP(0, m, 1)) % M * distribute(cnt[i], pref[i - 1] + 1) % M; add(ret, value); } } int answer = 0; for (int i = 0; i <= m; ++i) add(answer, f[n][i][0]); cout << answer << "\n"; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...