LightOJ 1288(01高斯消元、矩阵的秩)

来源:互联网 发布:历城二中 知乎 编辑:程序博客网 时间:2024/05/16 18:48

给你n个数 选出一些数 他们的乘积是完全平方数 求有多少种方案

每个数分解因子 每隔数可以选也可以不选 0 1表示 然后设有m种素数因子 选出的数组成的各个因子的数量必须是偶数

组成一个m行和n列的矩阵 每一行代表每一种因子的系数 解出自由元的数量

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <iostream>using namespace std;const int MAXN = 1010;const int mod = 1000000007;typedef int Matrix[MAXN][MAXN];typedef long long LL;int prime[MAXN];bool is_prime[MAXN];int tol;Matrix a;LL pow_mod(LL a, LL p, LL n){    LL ans = 1;    while(p)    {        if(p&1)        {            ans *= a;            ans %= n;        }        a *= a;        a %= n;        p >>= 1;    }    return ans;}void find_prime(){    memset(is_prime,false,sizeof(is_prime));    tol=0;    is_prime[1]=1;    for(int i=2; i<MAXN; i++)    {        if(!is_prime[i])            prime[tol++]=i;        if(!is_prime[i])        {            for(int j=i*2; j<MAXN; j+=i)                is_prime[j]=1;        }    }}int Gauss(int equ, int var){    int max_r,col,k;    for(k=0,col=0;k<equ&&col<var;k++,col++)    {        max_r=k;        for(int i=k+1;i<equ;i++)        {            if(abs(a[i][col])>abs(a[max_r][col])) max_r=i;        }        if(a[max_r][col]==0)        {            k--;            continue;        }        if(max_r!=k)        {            for(int j=col;j<var+1;j++)            {                swap(a[k][j],a[max_r][j]);            }        }        for(int i=k+1;i<equ;i++)        {            if(a[i][col]!=0)            {                for(int j=col;j<var+1;j++)                {                    a[i][j]^=a[k][j];                }            }        }    }    return var-k;}int main(){//    freopen("in.txt","r",stdin);//    freopen("out.txt","w",stdout);    find_prime();    int T;    cin>>T;    for(int cas=1; cas<=T; cas++)    {        memset(a,0,sizeof(a));        int n;        cin>>n;        int var=0;        for(int i=0; i<n; i++)        {            LL x;            cin>>x;            for(int j=0; j<tol&&x>=prime[j]; j++)            {                while(x%prime[j]==0)                {                    var=max(var,j+1);                    x/=prime[j];                    a[j][i]^=1;                }            }        }        int rk=Gauss(var,n);        printf("Case %d: %lld\n",cas,pow_mod(2,rk,mod)-1);    }    return 0;}
0 0