思路:完全平方数是指每个质因子次数均是偶数的数。现在要求n个数中选任意个使得组成得数是完全平方数,本质就是要求选的数中的每种质因子出现次数都是偶数次,而又给出最大因子是2000以内,也就是303个质因子,可以想到对每个质因子都需要满足一个异或方程(所有希望选的数对该质因子的亦或起来是0),也就是有303个方程,构造系数矩阵,用高斯消元求解。
const int N = 305,M=2000;
int Matrix[N][N];
int Free_x[N]; //自由变元
int X_Ans[N]; //解集
int Free_num = 0; //自由变元数
int Guass(int Row, int Col) //系数矩阵的行和列
{
int row = 0, col = 0, max_r;
for (row = 0;row < Row&&col < Col;row++, col++)
{
max_r = row;
for (int i = row + 1;i < Row;i++) //找出当前列最大值
if (abs(Matrix[i][col]) > abs(Matrix[max_r][col]))
max_r = i;
if (Matrix[max_r][col] == 0) //记录自由变元
{
row--;
Free_x[Free_num++] = col + 1;
continue;
}
if (max_r != row) //交换
for (int i = col;i < Col + 1;i++)
swap(Matrix[row][i], Matrix[max_r][i]);
for (int i = row + 1;i < Row;i++) //消元
{
if (Matrix[i][col] != 0)
{
for (int j = col;j < Col + 1;j++)
Matrix[i][j] ^= Matrix[row][j];
}
}
}
ll ans = quickmod(2, Col - row, mod) - 1;
return ans;
for (int i = row;i < Row;i++) //无解
if (Matrix[i][Col] != 0)
return 0;
if (row < Col) //无穷多解
{
ll ans = quickmod(2, Col - row, mod) - 1;
return ans;
}
//唯一解
for (int i = Col - 1;i >= 0;i--)
{
X_Ans[i] = Matrix[i][Col];
for (int j = i + 1;j < Col;j++)
X_Ans[i] ^= (Matrix[i][j] && X_Ans[j]);
}
return 1;
}
int p[M+1], cnt;
bool vis[M + 1];
void x_x()
{
f(i, 2, M)
{
if (!vis[i])p[++cnt] = i;
for (int j = 1;p[j] <= M / i;j++)
{
vis[p[j] * i] = true;
if (i%p[j] == 0)break;
}
}
}
int main()
{
//freopen("in.txt", "r", stdin);
x_x();
//debug(cnt);//303
int cas = 0;
int t = in();
while (t--)
{
//memset(Matrix, 0, sizeof Matrix);
int n = in();
f(i, 0, n-1)
{
ll x;
scanf("%lld", &x);
f(j, 1, 303)
{
int num = 0;
while (x%p[j] == 0)
{
num ^= 1;
x /= p[j];
}
Matrix[j - 1][i] = num;
}
}
ll ans=Guass(303, n);
printf("Case #%d:\n%d\n", ++cas, ans);
}
return 0;
}