还是矩阵树定理裸题。
不过这次的高斯消元有点意思,对1e9取模。
没逆元这可咋整qaq
辗转相除!orz
复杂度
O(n3log1e9)
O
(
n
3
l
o
g
1
e
9
)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 100
#define mod 1000000000
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
int nn,mm,n=0,a[N][N],id[10][10];
char s[N];
inline void add(int x,int y){
a[x][x]++;a[y][y]++;a[x][y]--;a[y][x]--;
}
inline void dec(int &x,ll y){x-=y;x%=mod;if(x<0) x+=mod;}
inline void Gauss(){
int ans=1;--n;
for(int i=1;i<=n;++i){
int r=i;
while(r<=n&&!a[r][i]) ++r;
if(r>n){puts("0");return;}
if(r!=i){ans*=-1;for(int j=i;j<=n;++j) swap(a[r][j],a[i][j]);}
for(int j=i+1;j<=n;++j){
while(a[j][i]){
int t=a[j][i]/a[i][i];
for(int k=i;k<=n;++k) dec(a[j][k],(ll)a[i][k]*t%mod);
if(!a[j][i]) break;ans*=-1;
for(int k=i;k<=n;++k) swap(a[j][k],a[i][k]);
}
}
}for(int i=1;i<=n;++i) ans=(ll)ans*a[i][i]%mod;
if(ans<0) ans+=mod;
printf("%d\n",ans);
}
int main(){
// freopen("a.in","r",stdin);
nn=read();mm=read();
for(int i=1;i<=nn;++i){
scanf("%s",s+1);
for(int j=1;j<=mm;++j){
if(s[j]=='*') continue;
id[i][j]=++n;
if(id[i-1][j]) add(id[i-1][j],id[i][j]);
if(id[i][j-1]) add(id[i][j-1],id[i][j]);
}
}Gauss();
return 0;
}