rt,我机智地想到了在 n<m 的时候交换 n,m,但是最后两个点依然卡不过去 。
#include<bits/stdc++.h>
#define N 110
#define M 600010
#define S 3000010
#define LL long long
#define ULL unsigned long long
#define DB double
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define INF 0x3f3f3f3f
#define pir pair<int,int>
#define mp(i,j) make_pair(i,j)
#define mod 20110520
#define fi first
#define se second
#define e(i,j) (((i)>>(j))&3)
#define w(i,j) ((i)<<(j))
using namespace std;
template <typename T> inline void read(T &a)
{
a=0;T w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){a=(a<<3)+(a<<1)+(ch^48);ch=getchar();}
a*=w;
}
template <typename T,typename ...Args> inline
void read(T &x,Args &...args){read(x);read(args...);}
int n,m;
LL ans;
bool rota,maap[N][N],cur;
char s[N];
struct HASH_TABLE
{
#define Mod 590027
struct NODE{int pre,id;}h[S];
int head[M],cc,pcc,st[S];LL f[S];
inline void init(){pcc=0;memset(head,0,sizeof(head));}
inline void insert(int x,LL val)
{
int key=x%Mod;
for(int cur=head[key];cur;cur=h[cur].pre) if(st[h[cur].id]==x){(f[h[cur].id]+=val)%=mod;return;}
f[++cc]=val;st[cc]=x;h[++pcc]={head[key],cc};head[key]=pcc;
}
#undef Mod
}hs[2];
signed main()
{
read(n,m);if(n<m) rota=1;
rep(i,1,n)
{
scanf("%s",s+1);
rep(j,1,m) rota ? maap[j][i]=(s[j]=='_') : maap[i][j]=(s[j]=='_');
}
if(rota) swap(n,m);
hs[0].init();hs[0].cc=1;hs[0].st[1]=0;hs[0].f[1]=1;
rep(i,1,n)
{
rep(j,1,hs[cur].cc) hs[cur].st[j]<<=2;
rep(j,1,m)
{
hs[cur^1].init();
cur^=1;hs[cur].cc=0;
rep(k,1,hs[cur^1].cc)
{
int sta=hs[cur^1].st[k];LL val=hs[cur^1].f[k];
int fr=e(sta,(j-1)*2),fd=e(sta,j*2);//0无插头 1已拐弯插头 2正拐弯插头 3未拐弯插头
int base=sta-w(fr,(j-1)*2)-w(fd,j*2);
if(!maap[i][j])
{
if(fr<=1&&fd<=1) hs[cur].insert(base,val);//白
}
else if(!fr&&!fd)
{
if(maap[i][j+1]) hs[cur].insert(base+w(3,j*2),val); //新建右插头
if(maap[i+1][j]) hs[cur].insert(base+w(3,(j-1)*2),val);//新建下插头
if(maap[i][j+1]&&maap[i+1][j]) hs[cur].insert(base+w(2,(j-1)*2)+w(2,j*2),val);//新建拐弯插头
}
else if(fr==1&&!fd)
{
if(maap[i][j+1]) hs[cur].insert(base+w(3,j*2),val); //新建右插头
if(maap[i+1][j]) hs[cur].insert(base+w(3,(j-1)*2),val);//新建下插头
if(maap[i][j+1]&&maap[i+1][j]) hs[cur].insert(base+w(2,(j-1)*2)+w(2,j*2),val);//新建拐弯插头
hs[cur].insert(base+w(1,j*2),val); //延续右插头
}
else if(fr==2&&!fd)
{
hs[cur].insert(base+w(1,j*2),val); //拐弯右插头
}
else if(fr==3&&!fd)
{
if(maap[i][j+1]) hs[cur].insert(base+w(3,j*2),val); //延续右插头
if(maap[i+1][j]) hs[cur].insert(base+w(2,(j-1)*2),val);//开始拐弯右插头
}
else if(!fr&&fd==1)
{
if(maap[i][j+1]) hs[cur].insert(base+w(3,j*2),val); //新建右插头
if(maap[i+1][j]) hs[cur].insert(base+w(3,(j-1)*2),val);//新建下插头
if(maap[i][j+1]&&maap[i+1][j]) hs[cur].insert(base+w(2,(j-1)*2)+w(2,j*2),val);//新建拐弯插头
hs[cur].insert(base+w(1,(j-1)*2),val); //延续下插头
}
else if(fr==1&&fd==1)
{
if(maap[i][j+1]) hs[cur].insert(base+w(3,j*2),val); //新建右插头
if(maap[i+1][j]) hs[cur].insert(base+w(3,(j-1)*2),val);//新建下插头
if(maap[i][j+1]&&maap[i+1][j]) hs[cur].insert(base+w(2,(j-1)*2)+w(2,j*2),val);//新建拐弯插头
hs[cur].insert(base+w(1,(j-1)*2),val); //延续下插头
hs[cur].insert(base+w(1,j*2),val); //延续右插头
}
else if(fr==2&&fd==1)
{
hs[cur].insert(base+w(1,j*2),val); //拐弯右插头
}
else if(fr==3&&fd==1)
{
if(maap[i][j+1]) hs[cur].insert(base+w(3,j*2),val); //延续右插头
if(maap[i+1][j]) hs[cur].insert(base+w(2,(j-1)*2),val);//开始拐弯右插头
}
else if(!fr&&fd==2)
{
hs[cur].insert(base+w(1,(j-1)*2),val); //拐弯下插头
}
else if(fr==1&&fd==2)
{
hs[cur].insert(base+w(1,(j-1)*2),val); //拐弯下插头
}
else if(fr==2&&fd==2){}
else if(fr==3&&fd==2){}
else if(!fr&&fd==3)
{
if(maap[i+1][j]) hs[cur].insert(base+w(3,(j-1)*2),val);//延续下插头
if(maap[i][j+1]) hs[cur].insert(base+w(2,j*2),val); //开始拐弯下插头
}
else if(fr==1&&fd==3)
{
if(maap[i+1][j]) hs[cur].insert(base+w(3,(j-1)*2),val);//延续下插头
if(maap[i][j+1]) hs[cur].insert(base+w(2,j*2),val); //开始拐弯下插头
}
else if(fr==2&&fd==3){}
else if(fr==3&&fd==3)
{
hs[cur].insert(base,val); //直接拐弯
}
}
}
}
rep(i,1,hs[cur].cc)
{
bool suc=1;
rep(j,0,n) if(e(hs[cur].st[i],j*2)>1){suc=0;break;}
if(suc) (ans+=hs[cur].f[i])%=mod;
}
printf("%lld\n",ans);
return 0;
}