题目大意:给出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][],p[MAX],v[MAX],a[MAX],cnt,n;//c存矩阵,p存素数表,cnt代表素数的个数 void MakeTab()//打素数表
{
int i,j;
memset(v,,sizeof(v));
memset(p,,sizeof(p));
cnt=;
for(i=; i<=; i++)
{
if(!v[i])
{
p[++cnt]=i;
for(j=i; j<=; j+=i)
{
v[j]=;
}
}
}
} int Rank()//计算秩
{
int i,j,k,r,u;
i=;
j=;
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+; 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=,T;
scanf("%d",&T);
while(T--)
{
scanf("%lld",&n);
memset(c,,sizeof(c));
for(i=; i<=n; i++)
{
scanf("%lld",&a[i]);
} for(i=; i<=n; i++)
{
for(j=; j<=cnt; j++)
{
long long num=a[i];
if(num%p[j]==)
{
while(num%p[j]==)
{
num/=p[j];
c[j][i]=c[j][i]^;
}
}
}
} long long k=(n-Rank());
long long ans=;
for(i=; i<=k; i++)
ans=(ans*)%MOD;
printf("Case #%d:\n",cns++);
printf("%lld\n",ans-);//去掉全0的解
}
return ;
}

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

  1. hdu 5833 Zhu and 772002 异或方程组高斯消元

    ccpc网赛卡住的一道题 蓝书上的原题 但是当时没看过蓝书 今天又找出来看看 其实也不是特别懂 但比以前是了解了一点了 主要还是要想到构造异或方程组 异或方程组的消元只需要xor就好搞了 数学真的是硬 ...

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

    300个最大质因数小于2000的数,选若干个它们的乘积为完全平方数有多少种方案. 合法方案的每个数的质因数的个数的奇偶值异或起来为0. 比如12=2^2*3,对应的奇偶值为01(2的个数是偶数为0,3 ...

  3. 3364 Lanterns (异或方程组高斯消元)

    基本思路.首先构造一个n*(m+1)的矩阵,同时标记一个行数row,row从零开始,然后找出每一列第一个非零的数,和第row行互换, 然后对row到n行,异或运算.最终的结果为2^(m-row) #i ...

  4. hdu 5833 Zhu and 772002 ccpc网络赛 高斯消元法

    传送门:hdu 5833 Zhu and 772002 题意:给n个数,每个数的素数因子不大于2000,让你从其中选则大于等于1个数相乘之后的结果为完全平方数 思路: 小于等于2000的素数一共也只有 ...

  5. HDU 5833 Zhu and 772002

    HDU 5833 Zhu and 772002 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  6. HDU 5833 Zhu and 772002 (高斯消元)

    Zhu and 772002 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5833 Description Zhu and 772002 are b ...

  7. hdu 5833 Zhu and 772002 高斯消元

    Zhu and 772002 Problem Description Zhu and 772002 are both good at math. One day, Zhu wants to test ...

  8. HDU 2262 Where is the canteen 期望dp+高斯消元

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2262 Where is the canteen Time Limit: 10000/5000 MS ...

  9. 【HDU 3949】 XOR (线性基,高斯消元)

    XOR Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

随机推荐

  1. hdu_2717_Catch That Cow_bfs

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2717 题解:一维简单BFS,详细看代码,0ms. #include<cstdio> #in ...

  2. 5、Web应用程序中的安全向量 -- Open Redirect Attack(开放重定向)

    开放重定向攻击的概念:那些通过请求(如查询字符串和表单数据)指定重定向URL的Web应用程序可能会被篡改,而把用户重定向到外部的恶意URL. 在执行重定向之前需先检查目标地址的有效性,可使用Url.I ...

  3. Android ListView 无法响应onItemClick事件

    当在布局文件中加入了Button.ImageButton.CheckBox.RadioButton等控件(也就是Button或者Checkable的子类控件)的时候,listView是无法响应onIt ...

  4. Java 相关注意事项小结

    程序是一系列有序指令的集合: Java主要用于开发两类程序: 1)桌面应用程序2)Internet应用程序1,Java程序:三步走,编写--编译--运行:2,使用记事本开发:1)以.java为后缀名保 ...

  5. web通知

    <html> <head> <title>桌面通知</title> <meta name="description" cont ...

  6. Openjudge-计算概论(A)-整数奇偶排序

    描述: 输入10个整数,彼此以空格分隔重新排序以后输出(也按空格分隔),要求:1.先输出其中的奇数,并按从大到小排列:2.然后输出其中的偶数,并按从小到大排列.输入任意排序的10个整数(0-100), ...

  7. vb6加载时提示出错,窗体log文件中错误信息为:控件 XX 的类 MSComctlLib.ListView 不是一个已加载的控件类。

    解决办法:单击[工程] -- [部件] 添加此Microsoft Windows Common Controls-6.0 (SP6)部件,如果列表中没有,浏览到~\project\包\Support中 ...

  8. wcf中的使用全双工通信

    wcf中的契约通信默认是请求恢复的方式,当客户端发出请求后,一直到服务端回复时,才可以继续执行下面的代码. 除了使用请求应答方式的通信外,还可以使用全双工.下面给出例子: 1.添加一个wcf类库 2. ...

  9. ios NSComparator 三种枚举类型

    NSComparator有3种枚举类型 NSOrderedDescending 降序,但是用他可以实现升序或者降序都没问题. NSOrderedAscending 升序,但是目前没有使用出任何效果.. ...

  10. C++ 使用string一行一行读取文件

    c++ 读取文件中的一行一行数据 通用模板: std::ifstream in(dictpath); if(!in) { std::cout << __DATE__ << &q ...