照着题解 贺 打的,但是第九个点 TLE,死活卡不过去,也不知道哪锅了,求卡常 / 调锅
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,m,mp[25][25];
int mxx,mxy;
int now,lst=1;
ll ans,dp[2][600005];
int sts[2][600005],cnt[2];
struct nd{
int prv,real;
}arr[600005];
int null[600005],acnt;
const short dob[35]={0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50};
#define db(x) dob[x]
inline void upd(int sta,ll v){
int id=sta%590027;
for(int nw=null[id];nw;nw=arr[id].prv) if(sta==sts[now][arr[nw].real]){
dp[now][arr[nw].real]+=v;
return;
}
sts[now][++cnt[now]]=sta;
dp[now][cnt[now]]=v;
arr[++acnt]={null[id],cnt[now]};
null[id]=acnt;
}
int main(){
ios::sync_with_stdio(0);
cin>>n>>m;
char c;
for(short i=1;i<=n;i++){
for(short j=1;j<=m;j++){
cin>>c;
if(c=='.'){
mp[i][j]=1;
mxx=i,mxy=j;
}
}
}
dp[0][1]=cnt[0]=1;
sts[0][1]=0;
for(short i=1;i<=n;i++){
for(int j=1;j<=cnt[now];j++) sts[now][j]<<=2;
for(short j=1;j<=m;j++){
acnt=0;
memset(null,0,sizeof(null));
swap(lst,now);
cnt[now]=0;
for(register int k=1;k<=cnt[lst];k++){
const int st=sts[lst][k];
const ll as=dp[lst][k];
const short d=(st>>db(j))&3,r=(st>>db(j-1))&3;
if(!mp[i][j]){
if(!d&&!r) upd(st,as);
}else if(!d&&!r){
if(mp[i][j+1]&&mp[i+1][j]) upd(st+(1<<db(j-1))+(2<<db(j)),as);
}else if(!d&&r){
if(mp[i+1][j]) upd(st,as);
if(mp[i][j+1]) upd(st-(r<<db(j-1))+(r<<db(j)),as);
}else if(!r&&d){
if(mp[i][j+1]) upd(st,as);
if(mp[i+1][j]) upd(st+(d<<db(j-1))-(d<<db(j)),as);
}else if(d==1&&r==1){
register int qwq=1;
for(short x=j+1;x<=m;x++){
short tmp=(st>>db(x))&3;
if(!(tmp==1?++qwq:tmp==2?--qwq:1)){
upd(st-(int)(1<<db(x))-(1<<db(j))-(1<<db(j-1)),as);
break;
}
}
}else if(d==2&&r==2){
register int qwq=1;
for(short x=j-2;~x;x--){
short tmp=(st>>db(x))&3;
if(!(tmp==1?--qwq:tmp==2?++qwq:1)){
upd(st+(int)(1<<db(x))-(2<<db(j))-(2<<db(j-1)),as);
break;
}
}
}else if(d==1&&r==2) upd(st-(2<<db(j-1))-(1<<db(j)),as);
else if(d==2&&r==1) if(i==mxx&&j==mxy) ans+=as;
}
}
}
cout<<ans<<endl;
return 0;
}