Educational Codeforces Round 107 E. Colorings and Dominoes

在这里插入图片描述
思路:求出当前两个位置上放上横条或者数条的概率,答案即为 2 w ∗ P 2^w*P 2wP

#include <iostream>
using namespace std;
typedef long long LL;
const int N = 3e5 + 10;
const int mod = 998244353;
LL qmi(int a, int b, int mod)
{
    
    
	LL res = 1;
	while (b)
	{
    
    
		if (b & 1) res = (LL)res * a % mod;
		a = (LL)a * a % mod;
		b >>= 1;
	}
	return res;
}
int inv(int x)
{
    
    
	return qmi(x, mod - 2, mod);
}
int divide(int x)
{
    
    
	if (x % 2 == 0) return 1 * inv(qmi(2, x, mod));
	else return -1 * inv(qmi(2, x, mod));
}
LL f[N], sum[N];
string s[N];
int main()
{
    
    
	for (int i = 2; i < N; ++i)
	{
    
    
		f[i] = f[i - 1] + divide(i);
		sum[i] = (sum[i - 1] + f[i]) % mod;
	}
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < n; ++i) cin >> s[i];
	LL res = 0, cnt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < m; ++j)
			if (s[i][j] == 'o') cnt++;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < m; ++j)
		{
    
    
			if (s[i][j] == 'o')
			{
    
    
				int tmp = 1;
				while (j + 1 < m && s[i][j + 1] == 'o') j++, tmp++;
				res = (res + sum[tmp]) % mod;
			}
		}
	for (int i = 0; i < m; ++i)
		for (int j = 0; j < n; ++j)
		{
    
    
			if (s[j][i] == 'o')
			{
    
    
				int tmp = 1;
				while (j + 1 < n && s[j + 1][i] == 'o') j++, tmp++;
				res = (res + sum[tmp]) % mod;
			}
		}
	cout << (res * qmi(2, cnt, mod) % mod + mod) % mod << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/wenyisir/article/details/115701986