CF EDU 107 E - Colorings and Dominoes
阿新 • • 發佈:2022-05-19
E - Colorings and Dominoes
DP + 算貢獻
首先觀察到每一行的貢獻和每一列的貢獻是獨立的,所以可以單獨算出每一行和每一列的貢獻之和
對某一行考慮
設 \(f[i][0]\) 為第 \(i\) 個元素可作為放骨牌的第一個位置的概率,\(f[i][1]\) 為第 \(i\) 個元素可作為放骨牌的第二個位置的概率
轉移:
\(f[i][0]=\frac12*(1-f[i-1][0])\)
\(f[i][1] = \frac12*f[i-1][0]\)
\(*\frac12\) 為只有一半的概率是該顏色
答案為 \(f[i][1]\) 之和 * 總方案數(\(2^{白色的方格數}\)
#include <iostream> #include <cstring> #include <algorithm> #include <vector> #include <cmath> using namespace std; typedef long long ll; const int mod = 998244353; const int N = 3e5 + 10; ll f[N][2]; int n, m, cnt; ll qmi(ll a, ll b) { ll ans = 1; while(b) { if (b & 1) ans = ans * a % mod; a = a * a % mod; b >>= 1; } return ans % mod; } int main() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); cin >> n >> m; vector<vector<char> > s(n + 10, vector<char> (m + 10)); for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cin >> s[i][j]; if (s[i][j] == 'o') cnt++; } } ll ans = 0; ll tot = qmi(2, cnt), inv2 = qmi(2, mod - 2); for (int i = 1; i <= n; i++) { f[0][0] = 0; ll now = 0; for (int j = 1; j <= m; j++) { if (s[i][j] == '*') { f[j][0] = f[j][1] = 0; continue; } f[j][0] = inv2 * (1 - f[j-1][0] + mod) % mod; f[j][1] = inv2 * f[j-1][0] % mod; now = (now + f[j][1]) % mod; } ans = (ans + tot * now % mod) % mod; } for (int j = 1; j <= m; j++) { f[0][0] = 0; ll now = 0; for (int i = 1; i <= n; i++) { if (s[i][j] == '*') { f[i][0] = f[i][1] = 0; continue; } f[i][0] = inv2 * (1 - f[i-1][0] + mod) % mod; f[i][1] = inv2 * f[i-1][0] % mod; now = (now + f[i][1]) % mod; } ans = (ans + tot * now % mod) % mod; } cout << ans << endl; return 0; }