神仙的博客
\(\tt notice:\)
只有右插头和左插头可以合并,左插头和右插头只可以合并一次
#include
typedef long long ll;
using namespace std;
const int N=12;
const int M=1595323;
const int mod=500009;
int n,m,mp[N+5][N+5];
int p3[N+5],now=0,ex,ey;
ll ans;
int ch(char x){return x=='*'||x=='.';}
struct Hash
{
int mak[M],E;
ll dp[M];
int h[mod],nxt[M];
void clear()
{
for(int i=0;i s;
for(int i=0;i<=m;i++)
{
s.push_back(mas%3);
mas/=3;
}
int d=0;
for(int i=x;i<=m;i++)
{
if(s[i]==1) d++;
if(s[i]==2) d--;
if(d==0) return i;
}
return -1;
}
int f2(int mas,int x)
{
vector s;
for(int i=0;i<=m;i++)
{
s.push_back(mas%3);
mas/=3;
}
int d=0;
for(int i=x;i>=0;i--)
{
if(s[i]==1) d++;
if(s[i]==2) d--;
if(d==0) return i;
}
return -1;
}
void up2(int x,int y)
{
D[now].clear();
for(int i=1;i<=D[now^1].E;i++)
{
int mas=D[now^1].mak[i];
ll dp=D[now^1].dp[i];
int b1=get(mas,y-1),b2=get(mas,y);
if(!b1&&!b2)
{
cha(mas,y-1,1);
cha(mas,y,2);
D[now].add(mas,dp);
}
else if(!b1&&b2)
{
D[now].add(mas,dp);
cha(mas,y,0);
cha(mas,y-1,b2);
D[now].add(mas,dp);
}
else if(b1&&!b2)
{
D[now].add(mas,dp);
cha(mas,y-1,0);
cha(mas,y,b1);
D[now].add(mas,dp);
}
else if(b1==b2)
{
if(b1==1&&b2==1)
{
int d1=f1(mas,y);
cha(mas,y-1,0);
cha(mas,y,0);
cha(mas,d1,1);
D[now].add(mas,dp);
}
else
{
int d2=f2(mas,y-1);
cha(mas,y-1,0);
cha(mas,y,0);
cha(mas,d2,2);
D[now].add(mas,dp);
}
}
else if(b1==2&&b2==1)
{
cha(mas,y-1,0);
cha(mas,y,0);
D[now].add(mas,dp);
}
else if(x==ex&&y==ey)
{
cha(mas,y-1,0),cha(mas,y,0);
if(mas==0) ans+=dp;
}
}
return;
}
int main()
{
p3[0]=1;
for(int i=1;i<=N+1;i++) p3[i]=p3[i-1]*3;
scanf("%d%d",&n,&m);
char w;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
while(!ch(w=getchar()));
mp[i][j]=w=='*'?1:0;
if(!mp[i][j]) ex=i,ey=j;
}
}
D[0].add(0,1);
for(int i=1;i<=n;i++)
{
now^=1;
tcol();
for(int j=1;j<=m;j++)
{
now^=1;
if(mp[i][j]) up1(i,j);
else up2(i,j);
}
}
printf("%lld\n",ans);
return 0;
}