思路:
和HDU 5833 一样,只不过这次uva数据稍微少一点而已!
通过这次题目懂得了,高斯消元 题目,消元都是小事,难点在于构造矩阵!
例如有4个数 4,6,10,15.
素因子只有2,3,5.
2,3,5
4 -> (2,0,0);
6 -> (1,1,0);
10 ->(1,0,1);
15-> (0,1,1);
因此可以构造一个对2取模的01方程组!
每一行是不同素因子,每一列是那个素因子的个数!来构成选出来的数的乘积!
消元求出自由元即可!
注意long long
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn = 500 + 5;
int equ, var;
int a[maxn][maxn];
int x[maxn];
int free_x[maxn];
int free_num;
int vis[maxn];
vector<int >prime;
int len_prime;
int Gauss(){
int max_r,col,k;
free_num = 0;
for (k = 0, col = 0; k < equ && col < var; k++, col++){
max_r = k;
for (int i = k+1; i < equ; i++){
if (abs(a[i][col]) > abs(a[max_r][col]))
max_r = i;
}
if (a[max_r][col] == 0){
k--;
free_x[free_num++] = col;
continue;
}
if (max_r != k){
for (int j = col; j < var+1; j++)
swap(a[k][j],a[max_r][j]);
}
for (int i = k+1; i < equ; i++){
if (a[i][col] != 0){
for (int j = col; j < var+1; j++)
a[i][j] ^= a[k][j];
}
}
}
for (int i = k; i < equ; i++)
if (a[i][col] != 0)
return -1;
if (k < var)return var- k;
for (int i = var-1; i >= 0; --i){
x[i] = a[i][var];
for (int j = i+1; j < var; j++)
x[i] ^= (a[i][j] && x[j]);
}
return 0;
}
void init(){
int len = sqrt(maxn) + 1;
for (int i = 2; i <= len; ++i) if (!vis[i])
for (int j = i*i; j < maxn; j+=i) vis[j] = 1;
for (int i = 2; i < maxn; ++i)if (!vis[i])prime.push_back(i);
len_prime = (int)prime.size();
}
int main(){
init();
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
memset(a,0,sizeof a);
for (int i = 0; i < n; ++i){
ll x;
scanf("%lld",&x);
for (int j = 0; j < len_prime; ++j){
int pri = prime[j];
while(x % pri == 0){
a[j][i] ^= 1;
x/=pri;
}
if (x == 1)break;
}
}
equ = len_prime;
var = n;
int t = Gauss();
printf("%lld\n",( 1ll << t )-1ll);
}
return 0;
}