记录编号 86113 评测结果 AAAAAAAAAA
题目名称 [UVa 11542] 乘积是平方数 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 0.112 s
提交时间 2014-01-20 21:06:01 内存使用 2.30 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<iomanip>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
const int SIZEP=510,SIZEN=510;
vector<int> prime;
void getprime(int n){
	bool flag[SIZEP]={0};
	for(int i=2;i<=n;i++){
		if(!flag[i]){
			prime.push_back(i);
			for(int j=i*i;j<=n;j+=i) flag[j]=true;
		}
	}
}
int xor_rank(ll A[SIZEN][SIZEN],int b[SIZEN],int n,int m){
	//使用高斯约当消元法,求异或方程组的秩
	//A是异或方程组,b是方程右边的常数向量,n是行数,m是列数
	int i,j,k;
	for(i=1;i<=n;i++){//第i次消元
		for(k=i;k<=m;k++){//选取消元列
			for(j=i;j<=n;j++){//选取消元行
				if(A[j][k]) goto BREAK;
			}
		}
		BREAK:;
		if(j==n+1) break;//找不到可消元的元素了
		if(i!=j){//交换行
			for(int km=1;km<=m;km++) swap(A[i][km],A[j][km]);
			swap(b[i],b[j]);
		}
		if(i!=k) for(int km=1;km<=n;km++) swap(A[km][i],A[km][k]);//交换列
		for(j=1;j<=n;j++){//消元
			if(j==i) continue;
			if(A[j][i]){
				for(int km=1;km<=m;km++) A[j][km]^=A[i][km];
				b[j]^=b[i];
			}
		}
	}
	return i-1;
}
int N,M;
ll A[SIZEN][SIZEN]={0};
int b[SIZEN]={0};
void work(void){
	scanf("%d",&N);
	memset(A,0,sizeof(A));
	memset(b,0,sizeof(b));
	int i,j;
	ll x;
	for(i=1;i<=N;i++){
		scanf("%lld",&x);
		j=0;
		while(x>1&&j<M){
			while(x%prime[j]==0){
				A[j+1][i]^=1;
				x/=prime[j];
			}
			j++;
		}
	}
	ll ans=xor_rank(A,b,M,N);
	ans=N-ans;
	cout<<(1LL <<ans)-1<<endl;//这里的LL很重要
}
int main(){
	freopen("square1.in","r",stdin);
	freopen("square1.out","w",stdout);
	getprime(500);
	M=prime.size();
	int T;
	scanf("%d",&T);
	while(T--) work();
	return 0;
}