[51nod1323]完美平方

来源:互联网 发布:linux中如何删除用户 编辑:程序博客网 时间:2024/05/16 10:47

Description

给出一个n*n的矩阵,求有多少种选择数的方案,使得每行每列均选择了奇数个数,并且选择的数的乘积为完全平方数
n<=20

Solution

完全平方数是什么,就是所有质因子的出现次数均为偶数
这样就变成了一堆奇偶的限制,异或方程组求自由元个数
高斯消元即可
感觉自己之前又打了假的高斯消元

Code

#include <cstdio>#include <cstring>#include <algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)using namespace std;#define P(x,y) ((x-1)*n+y)const int N=905,P=9*N+2*N+5,Mo=1e9+7;struct Prime{int p,r,bl;}pri[P];bool cmp(Prime x,Prime y) {return x.p<y.p;}int n,x,tot,num,ty;bool f[P][N];int main() {    for(scanf("%d",&ty);ty;ty--) {        scanf("%d",&n);tot=0;        fo(i,1,n)            fo(j,1,n) {                scanf("%d",&x);                for(int k=2;k*k<=x;k++) {                    if (!(x%k)) pri[++tot].p=k,pri[tot].bl=P(i,j),pri[tot].r=0;                    while (!(x%k)) x/=k,pri[tot].r++;                }                if (x>1) pri[++tot].p=x,pri[tot].bl=P(i,j),pri[tot].r=1;            }        sort(pri+1,pri+tot+1,cmp);        memset(f,0,sizeof(f));num=0;        fo(i,1,n) {            num++;            fo(j,1,n) f[num][P(i,j)]=1;            f[num][0]=1;        }        fo(i,1,n) {            num++;            fo(j,1,n) f[num][P(j,i)]=1;            f[num][0]=1;        }        fo(i,1,tot) {            if (pri[i].p!=pri[i-1].p) {                num++;                fo(j,0,n*n) f[num][j]=0;            }            f[num][pri[i].bl]=pri[i].r%2;        }        int pos=1,ans=1;        fo(i,1,n*n) {            int now=-1;            fo(j,pos,num) if (f[j][i]) {now=j;break;}            if (now==-1) ans=(ans<<1)%Mo;            else swap(f[now],f[pos]),pos++;            fo(j,pos,num)                if (f[j][i])                    fo(k,0,n*n)                        f[j][k]^=f[pos-1][k];        }        bool ok=1;        fo(i,1,num) {            bool now=0;            fo(j,1,n*n) if (f[i][j]) {now=1;continue;}            if (!now&&f[i][0]) {ok=0;break;}        }        if (!ok) {printf("0\n");continue;}        printf("%d\n",ans);    }}
原创粉丝点击