人 大 常 数 傻
查看原帖
人 大 常 数 傻
251324
stntn楼主2023/3/11 17:46

rt,我机智地想到了在 n<mn<m 的时候交换 n,mn,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;
}
2023/3/11 17:46
加载中...