【UVA11542】Square(高斯消元)

题目大意:n个数,选几个数相乘,使积为平方数,求方案数。

题解:
给每个数分解质因数,用质因数的指数mod 2作为未知数,每个数中包含该质因数的指数mod 2作为参数,列方程。(因为目的是为了每个质因数指数mod 2为0)

#include<cstdio>
#include<cstring>
#include<algorithm>
using std::swap;
long long N,prime[100],pri_cnt;
bool isprime[505];
long long x_cnt,pr_id[505];
typedef bool Matrix[105][105];
Matrix A;
void getPrime()
{
    for(long long i=2;i<=500;i++)
    if(!isprime[i])
    {
        prime[pri_cnt++]=i;
        for(long long j=i*i;j<=500;j+=i)
            isprime[j]=1;
    }
}
void Init()
{
    x_cnt=0;
    memset(pr_id,0,sizeof pr_id);
    memset(A,0,sizeof A);
    long long a;
    scanf("%lld",&N);
    for(long long i=1,k;i<=N;i++)
    {
        scanf("%lld",&a);
        k=0;
        while((a>500||isprime[a])&&a!=1)
        {
            if(a%prime[k]==0&&pr_id[prime[k]]==0)
                pr_id[prime[k]]=++x_cnt;
            while(a%prime[k]==0)
            {
                a/=prime[k];
                A[pr_id[prime[k]]][i]^=1;
            }
            k++;
        }
        if(a!=1)
        {
            if(pr_id[a]==0)
                pr_id[a]=++x_cnt;
            A[pr_id[a]][i]^=1;
        }
    }
}
void Gauss()
{
    long long r,c,n=x_cnt,m=N,mxr;
    for(r=1,c=1;r<=n&&c<=m;r++,c++)
    {
        for(mxr=r;!A[mxr][c]&&mxr<=n;mxr++);
        if(mxr>n){r--;continue;}
        if(mxr!=r)swap(A[mxr],A[r]);
        for(long long i=1;i<=n;i++)
            if(i!=r&&A[i][c])
                for(long long j=1;j<=m;j++)
                    A[i][j]^=A[r][j];
    }
    long long ans=1LL<<(m-r+1);
    ans--;
    printf("%lld\n",ans);
}
int main()
{
    long long T;
    scanf("%lld",&T);
    getPrime();
    while(T--)
    {
        Init();
        Gauss();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值