记录编号 |
86113 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[UVa 11542] 乘积是平方数 |
最终得分 |
100 |
用户昵称 |
cstdio |
是否通过 |
通过 |
代码语言 |
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;
- }
-