BZOJ 4894: 天赋 矩阵树定理
code:
#include <cstring>
#include <cstdio>
#include <algorithm>
#define N 303
#define mod 1000000007
#define ll long long
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
char S[N];
int a[N][N],n;
int qpow(int x,int y)
{
int tmp=1;
for(;y;y>>=1,x=(ll)x*x%mod)
if(y&1) tmp=(ll)tmp*x%mod;
return tmp;
}
int INV(int x) { return qpow(x,mod-2); }
int gauss()
{
int ans=1,i,j,k;
for(i=2;i<=n;++i)
{
k=i;
for(j=i+1;j<=n;++j) if(a[j][i]>a[k][i]) k=j;
if(k!=i) swap(a[i],a[k]),ans*=-1;
if(!a[i][i]) return 0;
int inv=INV(a[i][i]);
for(j=i+1;j<=n;++j)
{
int t=(ll)((ll)inv*a[j][i]%mod+mod)%mod;
for(k=i;k<=n;++k) a[j][k]=(ll)(a[j][k]%mod-(ll)t*a[i][k]%mod+mod)%mod;
}
}
if(ans<0) ans+=mod;
for(i=2;i<=n;++i) ans=(ll)((ll)ans*a[i][i]%mod+mod)%mod;
return ans;
}
int main()
{
// setIO("input");
int i,j;
scanf("%d",&n);
for(i=1;i<=n;++i)
{
scanf("%s",S+1);
for(j=1;j<=n;++j)
{
if(S[j]=='1') // i->j
{
++a[j][j];
--a[i][j];
}
}
}
printf("%d\n",gauss());
return 0;
}

浙公网安备 33010602011771号