这题我们的想法是,把图横向和纵向分开来看。
显然横向和纵向都只需要考虑一种颜色。
问题变成了1*n的全o方格value和。
这个我们可以dp求出,把红蓝看成是01串。
长度为i的value和
等于长度为 i-1的value和 *2 加上长度为i-1的01串中末尾连续1为奇数个的串的个数。
然后就欢乐ac了
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=998244353;
ll dp[300005];
char s[300005];
ll poww[300005];
vector<int>pos1[300005],pos2[300005];
int main()
{
ll ji=1,ou=1;
dp[1]=0;
poww[0]=1;
poww[1]=2;
for(int i=2;i<=300000;i++)poww[i]=poww[i-1]*2%mod;
for(int i=2;i<=300000;i++)
{
ll tj=ji,to=ou;
ou=(tj+to+tj)%mod;
ji=to;
dp[i]=(2*dp[i-1]+tj)%mod;
}
int n,m;
scanf("%d%d",&n,&m);
int cnt=0;
ll ans=0;
for(int i=1;i<=n;i++)
{
scanf("%s",s+1);
for(int j=1;j<=m;j++)
if(s[j]=='o')pos1[i].push_back(j),pos2[j].push_back(i),cnt++;
}
for(int i=1;i<=n;i++)
{
int temp=0,last=-1;
for(auto x:pos1[i])
{
if(x==last+1)temp++,last=x;
else
{
ans=(ans+poww[cnt-temp]*dp[temp])%mod;
temp=1,last=x;
}
}
if(temp)
{
ans=(ans+poww[cnt-temp]*dp[temp])%mod;
}
}
for(int i=1;i<=m;i++)
{
int temp=0,last=-1;
for(auto x:pos2[i])
{
if(x==last+1)temp++,last=x;
else
{
ans=(ans+poww[cnt-temp]*dp[temp])%mod;
temp=1,last=x;
}
}
if(temp)
{
ans=(ans+poww[cnt-temp]*dp[temp])%mod;
}
}
printf("%lld",ans);
return 0;
}