【HDU 5833】Zhu and 772002(异或方程组高斯消元讲解)

题目大意:给出n个数字a[],将a[]分解为质因子(保证分解所得的质因子不大于2000),任选一个或多个质因子,使其乘积为完全平方数。求其方法数。

学长学姐们比赛时做的,当时我一脸懵逼的不会搞……所以第二天上午花了一上午学习了一下线性代数。

题目思路:

任选一个或多个质因子,起乘积为完全数m,因为组成它的均为素数,假设组成m的素数的种类为n,那么这n类素数中每类素数的个数应为偶数。

可设:a[i][j]=0代表第i种素数可在a[j]中分离出的个数为偶数,a[i][j]=1代表第i种素数可在a[j]中分离出的个数为奇数数。

          b[i]=1代表选择这类素数,b[i]=0代表不选择这类素数。

列出线性方程组:

a11x1+a12x2+...+a1nxn=0

a21x1+a22x2+...+a2nxn=0

...

an1x1+an2x2+...+annxn=0

求解的个数 ans

转化为矩阵形式:

矩阵A=

a11 a12 a13 …………a1n

a21 a22 a23 …………a2n

……………………………………

……………………………………

an1 an2 an3 …………ann

通过初等变换可将矩阵A换成类似下面矩阵B的形式

a11 a12 a13 ……a1n

0     a22 a23 ……a2n

0       0    a33……a3n

0       0    0    ……arn

再将矩阵B转化成线性方程组 可求出最后一组方程的解,倒着往回求可求出所有方程解

可解出的方程组共 r 个,由秩的定义可知 r等矩阵A的秩

由定理:

对于n元齐次线性方程组如果r<n,则方程组含n-r个自由未知量。

解的个数ans=2^(n-r)-1(减去全0解)

具体操作:

#include<cstdio>
#include<stdio.h>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#define INF 0x3f3f3f
#define MAX 2105
#define MOD 1000000007

using namespace std;

long long c[MAX][505],p[MAX],v[MAX],a[MAX],cnt,n;//c存矩阵,p存素数表,cnt代表素数的个数

void MakeTab()//打素数表
{
    int i,j;
    memset(v,0,sizeof(v));
    memset(p,0,sizeof(p));
    cnt=0;
    for(i=2; i<=2000; i++)
    {
        if(!v[i])
        {
            p[++cnt]=i;
            for(j=i; j<=2000; j+=i)
            {
                v[j]=1;
            }
        }
    }
}

int Rank()//计算秩
{
    int i,j,k,r,u;
    i=1;
    j=1;
    while(i<=cnt && j<=n)
    {
        r=i;
        while(!c[r][j] && r<=cnt)
            r++;
        if(c[r][j])
        {
            swap(c[i],c[r]);//如果发现了第r行第j列为1,就讲r行和i行行互换(初等行变换)
            for(u=i+1; u<=cnt; u++)
            {
                if(c[u][j])
                {
                    for(k=i; k<=n; k++)
                    {
                        c[u][k]=c[u][k]^c[i][k];//每找到一个未知数就对其进行亦或处理,去掉系数c[i][k]
                    }

                }
            }
            i++;
        }
        j++;
    }
    return i;
}

int main()
{
    MakeTab();
    int i,j,cns=1,T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld",&n);
        memset(c,0,sizeof(c));
        for(i=1; i<=n; i++)
        {
            scanf("%lld",&a[i]);
        }

        for(i=1; i<=n; i++)
        {
            for(j=1; j<=cnt; j++)
            {
                long long num=a[i];
                if(num%p[j]==0)
                {
                    while(num%p[j]==0)
                    {
                        num/=p[j];
                        c[j][i]=c[j][i]^1;
                    }
                }
            }
        }

        long long k=(n-Rank());
        long long ans=1;
        for(i=1; i<=k; i++)
            ans=(ans*2)%MOD;
        printf("Case #%d:\n",cns++);
        printf("%lld\n",ans-1);//去掉全0的解
    }
    return 0;
}

看懂了吗?耐点心伙计,我也是万分痛苦的学习了半天的线性代数的,由于学的时间比较短,或许某些细节有错误,如果发现有错的地方记得告诉我哦,我最近也会完善一下这篇博客的。

时间: 2024-08-06 11:39:18

【HDU 5833】Zhu and 772002(异或方程组高斯消元讲解)的相关文章

【HDU 5833】Zhu and 772002(异或方程组高斯消元)

300个最大质因数小于2000的数,选若干个它们的乘积为完全平方数有多少种方案. 合法方案的每个数的质因数的个数的奇偶值异或起来为0. 比如12=2^2*3,对应的奇偶值为01(2的个数是偶数为0,3的个数是奇数为1),3的对应奇偶值为01,于是12*3是完全平方数. 然后异或方程组就是: a11x1+a12x2+...+a1nxn=0 a21x1+a22x2+...+a2nxn=0 ... an1x1+an2x2+...+annxn=0 aij:第i个质数(2000内有303个质数)在第j个数

Luogu3164 CQOI2014 和谐矩阵 异或、高斯消元

传送门 题意:给出$N,M$,试构造一个$N \times M$的非全$0$矩阵,其中所有格子都满足:它和它上下左右四个格子的权值之和为偶数.$N , M \leq 40$ 可以依据题目中的条件列出有$N \times M$的元.$N \times M$个方程的异或方程组(异或方程组就是所有位置都是$1$或$0$,最右边一列的答案需要通过异或互相消除的方程组,一般在$mod\,2$意义下产生). 理论上元和方程组数量一致的时候每一个元都是有唯一解的,但是在有解的情况下,其中一些方程是线性相关的,

HDU 5833 Zhu and 772002(高斯消元)

题意:给n个数,从n个数中抽取x(x>=1)个数,这x个数相乘为完全平方数,求一共有多少种取法,结果模1000000007. 思路:每个数可以拆成素数相乘的形式,例如: x1 2=2^1 * 3^0 * 5^0; x2 3=2^0 * 3^1 * 5^0; x3 4=2^2 * 3^0 * 5^0; x4 5=2^0 * 3^0 * 5^1; x5 6=2^1 * 3^1 * 5^0; x6 15=2^0 * 3^1 * 5^1; 用xi表示第i个数选或不选,xi的取值为0或1:因为相乘结果为完

HDU 5833 Zhu and 772002(高斯消元)——2016中国大学生程序设计竞赛 - 网络选拔赛

传送门 Zhu and 772002 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 48    Accepted Submission(s): 16 Problem Description Zhu and 772002 are both good at math. One day, Zhu wants to test the abili

HDU 5833 Zhu and 772002 (数论+高斯消元)

题目链接 题意:给定n个数,这n个数的素因子值不超过2000,从中取任意个数使其变成完全平方数,问有多少种取法. 题解:开始用素筛枚举写了半天TLE了,后来队友说高斯消元才想起来,果断用模板.赛后又得知这是个原题,真坑啊.把每个数进行素因子分解,素因子a的幂为奇数则视为1,偶数则视为0,转化为从n个数中取数异或和为0有多少种取法的问题. AC代码: #include <cstdio> #include <cstring> #include <cmath> #includ

Hdu 5833 Zhu and 772002(高斯消元解异或方程组)

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=5833 思路: 将每个数质因数分解,若该位质因数指数为偶数,则该位a[i]为0,否则该位a[i]为1(记a[i]为质因数分解后第i个质数所对应值). 合法方案为积的各位质因子个数对应值a[i]异或值为0. 例3=3^1,4=2^2,则3*3*4对应: 2           3 0   (1 xor 1=0) 则可列方程组 a11x1+a12x2+...+a1nxn=0 a21x1+a22x2+...

NEFU 503 矩阵求解 (非01异或的高斯消元)

题目链接 中文题,高斯消元模板题. #include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <queue> #include <vector> #include <map> #include <ctime> using namespace std;

【BZOJ2466】【中山市选2009】树 高斯消元解异或方程组

广告: #include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/44356273"); } 题解: 参照此题解,也是我写的,俩题一样. [POJ1681]Painter's Problem 高斯消元,求最小∑系数的异或方程组 代码: #include <cmath> #include &

hdu-5833 Zhu and 772002(高斯消元)

题目链接: Zhu and 772002 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1006    Accepted Submission(s): 348 Problem Description Zhu and 772002 are both good at math. One day, Zhu wants to test the