UVa11542

11542 Square
Given n integers you can generate 2n??1 non-empty subsets from them. Determine for how many of these
subsets the product of all the integers in that is a perfect square. For example for the set f4,6,10,15g
there are 3 such subsets. f4g, f6,10,15g and f4,6,10,15g. A perfect square is an integer whose square
root is an integer. For example 1, 4, 9, 16, . . . .
Input
Input contains multiple test cases. First line of the input contains T (1 T 30) the number of test
cases. Each test case consists of 2 lines. First line contains n (1 n 100) and second line contains n
space separated integers. All these integers are between 1 and 1015. None of these integers is divisible
by a prime greater than 500.
Output
For each test case output is a single line containing one integer denoting the number of non-empty
subsets whose integer product is a perfect square. The input will be such that the result will always t
into signed 64 bit integer.
Sample Input
4
3
2 3 5
3
6 10 15
4
4 6 10 15
3
2 2 2
Sample Output
0
1
3
3

题意:
       给出n个整数,从中选出1个或者多个,使得选出的整数乘积是完全平方数,一共有多少种选法。该题输入的数的素因子都不超过500。

分析:

注意到“不含大于500的素因子”这一条件,我们将考虑每一个数的唯一分解式,并将其表示为01向量。具体来说,考虑一个矩阵,其中的元素(i,j)=1/0(i行j列)表示对于第j个整数,它第i个素因子的幂次是奇数/偶数。于是输入的n个数就可以被表示成这样一个m行n列的0/1矩阵。设这个矩阵是A。设一个解向量(列向量)X=(x1,x2,x3,…,xn)(xi = 1或者0,i = 1,2,…,n)。解向量的分量xi = 1表示要选取第i个数,反之不选。于是,选取一些数的乘积是完全平方数等价于AX=0(mod
2)。在mod 2的情况下为A的增广矩阵消元是容易的,这是因为,不需要做乘法和除法,每次只需要做的就是异或,每次也不需要找到绝对值最大的系数ari,任意一个ari = 1即可实现消元。

最后,假设消元后发现自由变元有f个,则线性方程的解一共有2^f。注意本题不能一个数都不选,所以,最终的答案需要减去1。即答案是2^f-1。f的值可以通过求系数矩阵的秩求得。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <algorithm>
 5 #include <iostream>
 6 using namespace std;
 7 const int maxn = 500;
 8 const int maxp = 100;
 9 const int MOD = 1e9;
10 typedef long long LL;
11 int vis[maxn + 1]; //vis[i] = 1是合数、vis[i] = 0是素数或者1
12 int prime[maxp + 1];
13 // 筛素数
14 void sieve(int n){
15     int m = (int)sqrt(n + 0.5); // 避免浮点误差
16     memset(vis,0,sizeof vis);
17     for(int i = 2 ; i <= m ; i++) if(!vis[i])
18         for(int j = i * i ; j <= n ; j += i) vis[j] = 1;
19 }
20 // 生成素数表,放在prime数组中,返回素数的个数
21 int gen_primes(int n){
22     sieve(n);
23     int c = 0;
24     for(int i = 2 ; i <= n ; i++)if(!vis[i])
25         prime[c++] = i;
26     return c;
27 }
28 typedef int Matrix[maxn + 1][maxn + 1];
29 // 一共m个方程,n个变量
30 int _rank(Matrix A,int m,int n){ // m行n列的01矩阵求秩,同时消元
31     int i = 0,j = 0,k,r,u;
32     while(i < m && j < n){ // 当前正在处理第i个方程、第j个变量
33         r = i;
34         for(k = i ; k < m ; k++)if(A[k][j]){
35             r = k;
36             break;
37         }
38         if(A[r][j]){
39             if(r != i)for(k = 0 ; k <= n ; k++)swap(A[r][k],A[i][k]);
40             // 消元后第i行第一个非零列是第j列,且u>i行的第j列均为0
41             for(u = i + 1 ; u < m ; u++) if(A[u][j])
42                 for(k = i ; k <= n ; k++) A[u][k] ^= A[i][k];
43             i++;
44         }
45         j++;
46     }
47     return i;
48 }
49 Matrix A;
50 int main(){
51     int m = gen_primes(maxn);
52     int T; scanf("%d",&T);
53     while(T--){
54         int n,_maxp = 0; scanf("%d",&n);
55         long long x;
56         memset(A,0,sizeof A);
57         for(int i = 0 ; i < n ; i++){
58             scanf("%lld",&x);
59             for(int j = 0 ; j < m ; j++)
60                 while(x % prime[j] == 0){
61                     _maxp = max(_maxp,j);
62                     x /= prime[j];
63                     A[j][i] ^= 1;
64                 }
65         }
66         int r = _rank(A,_maxp + 1,n); // 只用到了前_maxp+1个素数
67         printf("%lld\n",(1LL << (n - r)) - 1); // 空集不是解所以减1
68     }
69     return 0;
70 }

时间: 2024-12-25 01:30:49

UVa11542的相关文章

UVa11542 Square

1 /*by SilverN*/ 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #define LL long long 8 using namespace std; 9 const int mxn=1200; 10 int read(){ 11 int x=0,f=1;char ch=ge

UVA11542 Square(高斯消元 异或方程组)

建立方程组消元,结果为2 ^(自由变元的个数) - 1 采用高斯消元求矩阵的秩 #include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<map> #include<queue> #include<vector> #incl

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

《算法竞赛入门经典——训练指南》第二章题库

UVa特别题库 UVa网站专门为本书设立的分类题库配合,方便读者提交: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=442 注意,下面注有"extra"的习题并没有在书中出现,但在上面的特别题库中有,属于附加习题. 基础练习 (Basic Problems) UVa11388 GCD LCM UVa11889 Benefit UVa10943 How do y