题目描述:
给出n个整数,从中选出1个或多个,使得选出的整数的乘积是完全平方数。问一共有多少种选法。
输入格式:
输入第一行为一个整数t,即测试数据的数量。
每组数据包含两行,第一行为整数n,第二行包含n个整数。
输出格式:
对于每组数据,输出方案总数。
答案对109 + 7取模。
样例输入:
1 4 4 6 10 15
样例输出:
3
提示:
对于100%的数据,1 ≤ t ≤ 30,1 ≤ n ≤ 100,所有整数均不小于1,不大于1015,且不含大于500的素因子。
时间限制: 1000ms
空间限制: 256MB
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[105][105]={0},n,m=0;
ll b[105];
bool x[505]={0};
void f(){
for(int i=2;i<=500;i++) if(!x[i])
for(int j=2;j*i<=500;j++){
x[j*i]=1;
}
for(int i=2;i<=500;i++){
if(!x[i]){
b[++m]=i;
}
}
}
ll mm(){
int i=1,j=1;
while(i<=n&&j<=m){
int r=i;
for(;r<=n;r++){
if(a[r][j]){
break;
}
}
if(r<=n){
for(int k=0;k<=m;k++){
swap(a[i][k],a[r][k]);
}
for(int ii=0;ii<=n;ii++) if(a[ii][j]&&ii!=i)
for(int jj=0;jj<=m;jj++){
a[ii][jj]^=a[i][jj];
}
i++;
}
j++;
}
for(int k=i;k<n;k++) if(a[k][m])
return 0;
return (ll)1<<(n-i+1);
}
int main(){
int T;
cin>>T;
f();
while(T--){
ll x;
cin>>n;
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++){
cin>>x;
for(int j=1;j<=m;j++){
while(x%b[j]==0){
a[i][j]^=1;
x/=b[j];
}
}
}
cout<<mm()-1<<endl;
}
return 0;
}