首页 > 代码库 > uva 11542 高斯消元
uva 11542 高斯消元
Square
Input: Standard Input
Output: Standard Output
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 {4,6,10,15} there are 3 such subsets. {4}, {6,10,15} and {4,6,10,15}. 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 10^15. 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 fit into signed 64 bit integer.
Sample Input Output for Sample Input
4 3 2 3 5 3 6 10 15 4 4 6 10 15 3 2 2 2 | 0 1 3 3 |
Problemsetter: Abdullah al Mahmud
Special Thanks to: Manzurur Rahman Khan
题目大意:给n个整数,从中选1个或多个,他们的积是一个完全平方数。这样的情况有多少种?
解题思路:选s个整数出来(1<=s<=n),它们的积可以表示成a1^p1*a2.P2....an^pm,要想它是一个完全平方数,那pi必须是偶数。把每个数分解质因数,所有质因数的指数都模2,最后得出一个n*m的矩阵,进行消元,求出矩阵的秩r。那么就有n-r行每个元素都是0。从中选一行或多行(即求一个集合的真子集个数)都符合题目要求。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 typedef long long LL; 7 const int maxn=500; 8 const int maxm=105; 9 typedef int Matrix[maxm][maxm];10 int prime[maxn],num;11 bool flag[maxn];12 Matrix A;13 14 int max(int a,int b){ return a>b?a:b;}15 void swap(int& a,int& b){int t=a;a=b;b=t;}16 17 void get_primes()18 {19 int i,j;num=0;20 memset(flag,1,sizeof(flag));21 for(i=2;i<maxn;i++)22 {23 if(flag[i])prime[num++]=i;24 for(j=0;j<num&&i*prime[j]<maxn;j++)25 {26 flag[i*prime[j]]=false;27 if(i%prime[j]==0) break;28 }29 }30 }31 32 int rank(int n,int m)33 {34 int i=0,j=0,k,r,u;35 while(i<n&&j<m)36 {37 r=i;38 for(k=i;k<n;k++)39 if(A[k][j]){r=k;break;}40 if(A[r][j])41 {42 if(r!=i) for(k=0;k<=m;k++) swap(A[r][k],A[i][k]);43 for(u=i+1;u<n;u++) if(A[u][j])44 for(k=i;k<=m;k++) A[u][k]^=A[i][k];45 i++;46 }47 j++;48 }49 return i;50 }51 52 LL Pow(LL a,LL b)53 {54 LL ret=1;55 while(b)56 {57 if(b&1) ret*=a;58 a*=a;b>>=1;59 }60 return ret;61 }62 63 int main()64 {65 get_primes();66 int i,j,t,n,maxp;67 LL p;68 scanf("%d",&t);69 while(t--)70 {71 scanf("%d",&n);72 memset(A,0,sizeof(A));73 maxp=0;74 for(i=0;i<n;i++)75 {76 scanf("%lld",&p);77 for(j=0;j<num;j++)78 {79 if(p==1) break;80 while(p%prime[j]==0)81 {82 maxp=max(maxp,j);83 p/=prime[j];84 A[i][j]^=1;85 }86 }87 }88 int r=rank(n,maxp+1);89 printf("%lld\n",Pow(2,n-r)-1); 90 }91 return 0;92 }