bzoj 4031 [HEOI2015]小Z的房间
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4031
见TJ:https://blog.csdn.net/fromatp/article/details/53966305
因为模数不是质数,所以高斯消元里的那个除法不能用。所以辗转相除。
辗转相除的那个除法可以用。因为本质是在模意义下相减。那个除法不能用是因为乘上那个浮点数不一定能消成真的0。
其实不用把Matrix都弄出来。定义一个数组,直接在上面操作,邻接矩阵+1的时候直接减在那个矩阵上就行了。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #define ll long long using namespace std; const int N=85;const ll mod=1e9; int n,m,tot,dy[15][15]; ll ans=1; char ch[2][15]; bool fx; struct Matrix{ ll a[N][N]; Matrix(){memset(a,0,sizeof a);} Matrix operator - (const Matrix &b)const { Matrix c; for(int i=1;i<=tot;i++) for(int j=1;j<=tot;j++) c.a[i][j]=(a[i][j]-b.a[i][j]+mod)%mod; return c; } }d,l,r; void add(int x,int y) { d.a[x][x]++;d.a[y][y]++; l.a[x][y]=l.a[y][x]=1; } void gauss() { for(int i=1;i<=tot;i++) { int k=i; for(int j=i+1;j<=tot;j++)if(r.a[j][i]>r.a[k][i])k=j; if(k!=i) { fx=!fx;for(int l=i;l<=tot;l++)swap(r.a[i][l],r.a[k][l]); } for(int j=i+1;j<=tot;j++) while(r.a[j][i]) { ll tmp=r.a[i][i]/r.a[j][i]; for(int l=i;l<=tot;l++) { ll tp=r.a[i][l];r.a[i][l]=r.a[j][l]; // i=j r.a[j][l]=(tp-r.a[j][l]*tmp%mod+mod)%mod; // j=i%j } fx=!fx; } (ans*=r.a[i][i])%=mod; } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { int u=(i&1),v=!u; scanf("%s",ch[u]+1); for(int j=1;j<=m;j++) if(ch[u][j]=='.') { tot++;dy[u][j]=tot; if(ch[v][j]=='.')add(dy[v][j],tot); if(ch[u][j-1]=='.')add(dy[u][j-1],tot); } } r=d-l; tot--;gauss(); printf("%lld",fx?(-ans+mod)%mod:ans);//(-ans+mod)%mod return 0; }