BZOJ5133: [CodePlus2017年12月]白金元首与独舞
BZOJ5133: [CodePlus2017年12月]白金元首与独舞
https://lydsy.com/JudgeOnline/problem.php?id=4894
分析:
- 可以发现原来就确定的那些格子不会影响答案,除非有某个格子会使得出现环。
- 预处理出来每个格子会走到哪里,对每个不确定的格子向四周都走一下,向他们连边。
- 设走到外部为根,转化成有向树计数问题。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 305
#define mod 1000000007
typedef long long ll;
ll qp(ll x,ll y) {
ll re=1; for(;y;y>>=1,x=x*x%mod) if(y&1) re=re*x%mod; return re;
}
char g[N][N];
int n,vis[N][N],col[N][N],m;
int FLG=0,idx[N][N],to[N][N],tot;
ll a[N][N];
int dfs(int x,int y) {
if(vis[x][y]) {FLG=1; return -1;}
if(g[x][y]=='.') return idx[x][y];
if(x<1||x>n||y<1||y>m) return tot;
if(to[x][y]) return to[x][y];
vis[x][y]=1;
if(g[x][y]=='L') to[x][y]=dfs(x,y-1);
else if(g[x][y]=='R') to[x][y]=dfs(x,y+1);
else if(g[x][y]=='U') to[x][y]=dfs(x-1,y);
else to[x][y]=dfs(x+1,y);
vis[x][y]=0;
return to[x][y];
}
int tx[]={0,1,0,-1};
int ty[]={1,0,-1,0};
ll Gauss(int n) {
int i,j,k,flg=0; ll del,ans=1;
for(i=1;i<=n;i++) {
for(j=i;j<=n&&!a[j][i];j++) ;
if(j>n) continue;
if(i!=j) {
for(k=i;k<=n;k++) swap(a[i][k],a[j][k]); flg^=1;
}
for(j=i+1;j<=n;j++) if(a[j][i]) {
del=a[j][i]*qp(a[i][i],mod-2)%mod;
for(k=i;k<=n;k++) a[j][k]=(a[j][k]-a[i][k]*del)%mod;
}
}
for(i=1;i<=n;i++) ans=ans*a[i][i]%mod;
if(flg) ans=-ans;
return (ans+mod)%mod;
}
int main() {
/*freopen("a.in","r",stdin);
freopen("a.out","w",stdout)*/
int T;
scanf("%d",&T);
while(T--) {
memset(vis,0,sizeof(vis));
memset(a,0,sizeof(a));
memset(to,0,sizeof(to));
memset(idx,0,sizeof(idx));
scanf("%d%d",&n,&m);
int i,j;
for(i=1;i<=n;i++) scanf("%s",g[i]+1);
FLG=0;
tot=0;
for(i=1;i<=n;i++) for(j=1;j<=m;j++) if(g[i][j]=='.') idx[i][j]=++tot;
tot++;
for(i=1;i<=n;i++) {
for(j=1;j<=m;j++) if(g[i][j]!='.') {
dfs(i,j);
}
}
if(FLG) {puts("0"); continue;}
for(i=1;i<=n;i++) {
for(j=1;j<=m;j++) if(g[i][j]=='.') {
int x=i,y=j;
int k;
for(k=0;k<4;k++) {
int dx=x+tx[k], dy=y+ty[k];
if(g[dx][dy]=='.') to[x][y]=idx[dx][dy];
else if(dx<1||dx>n||dy<1||dy>m) to[x][y]=tot;
else to[x][y]=to[dx][dy];
a[idx[x][y]][idx[x][y]]++;
a[ to[x][y]][idx[x][y]]--;
}
}
}
/*for(i=1;i<tot;i++) {
for(j=1;j<tot;j++) printf("%lld ",a[i][j]);
puts("");
}*/
printf("%lld\n",Gauss(tot-1));
}
}