Uva 11542 Square

题目中说数组中的数的最大质因子不超过500,我们筛出≤500的质数,然后考虑对每个质数列一个方程组。。

然后这几乎就是高斯消元求解异或方程组的模板题了。。。。

注意答案是 2^(自由元数量)-1,因为空集不是答案的一部分。。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#define ll long long
#define maxn 125
using namespace std;
int zs[505],t=0;
bool v[505];

inline void init(){
	for(int i=2;i<=500;i++){
		if(!v[i]) zs[++t]=i;
		for(int j=1,u;j<=t&&(u=zs[j]*i)<=500;j++){
			v[u]=1;
			if(!(i%zs[j])) break;
		}
	}

}

int a[maxn][maxn];
int T,n,m;
ll now;

inline void prework(int x){
	for(int i=1;i<=t;i++) if(!(now%zs[i])){
		int c=0;
		while(!(now%zs[i])) now/=(ll)zs[i],c^=1;
		a[i][x]=c;
	}
}

inline int solve(){
	int i=1,j=1;
	//当前处理到第i个方程,第j个变量
	while(i<=t&&j<=n){
		for(int k=i;k<=t;k++) if(a[k][j]){
			if(k!=i) for(int l=j;l<=n;l++) swap(a[k][l],a[i][l]);
			break;
		}

		if(a[i][j]){
			for(int k=i+1;k<=t;k++) if(a[k][j])
			    for(int l=j;l<=n;l++) a[k][l]^=a[i][l];
			i++;
		}
		j++;
	}

	return i-1;
}

int main(){
	init();

	scanf("%d",&T);
	while(T--){
		memset(a,0,sizeof(a));
		scanf("%d",&n);

		for(int i=1;i<=n;i++){
			scanf("%lld",&now);
			prework(i);
		}

		int d=solve();

		printf("%lld\n",((ll)1<<(ll)(n-d))-1ll);
	}

	return 0;
}

  

原文地址:https://www.cnblogs.com/JYYHH/p/8447421.html

时间: 2024-10-19 08:19:24

Uva 11542 Square的相关文章

UVA 11542 - Square(高斯消元)

UVA 11542 - Square 题目链接 题意:给定一些数字,保证这些数字质因子不会超过500,求这些数字中选出几个,乘积为完全平方数,问有几种选法 思路:对每个数字分解成质因子后,发现如果要是完全平方数,选出来的数字的每个质因子个数都必然要是偶数,这样每个质因子可以列出一个异或的方程,如果数字包含质因子,就是有这个未知数,然后进行高斯消元,求出自由变量的个数,每个自由变量可以选或不选,这样的情况就是(2^个数),然后在扣掉什么都不选的1种就是答案了 代码: #include <cstdi

UVA - 11542 Square (异或方程组)

Given n integers you cangenerate 2n-1 non-empty subsets from them. Determine for howmany of these subsets the product of all the integers in that is a perfectsquare. For example for the set {4,6,10,15} there are3 such subsets. {4}, {6,10,15} and {4,6

高斯消元 UVA 11542 Square

题目传送门 题意:给n个数,选择一些数字乘积为平方数的选择方案数.训练指南题目. 分析:每一个数字分解质因数.比如4, 6, 10, 15,, , , , 令,表示选择第i个数字,那么,如果p是平方数,那么每个质因数上的指数为偶数,x1系数为2已经是偶数不考虑.可以转换为异或为0判断偶数,即奇数置为1,偶数置为0,然后n个数字m个质因数的增广矩阵消元看有几个自由变量(取0或1无所谓),答案是2^r - 1(全部都不取方案不算) #include <bits/stdc++.h> const in

UVA 11542 Square ——线性基

[题目分析] 每个数没有超过500的因子.很容易想到把每一个数表示成一个二进制的数. (0代表该质数的次数为偶数,1代表是奇数) 然后问题转化成了选取一些二进制数,使他们的异或和为0. 高斯消元,2^(自由元)即为答案,需要把空集的情况减去,所以减一. 然而发现并不需要知道哪些是自由元,所以只需要用线性基去维护即可. 然后代码就呼之欲出了. [代码] #include <cstdio> #include <cstring> #include <cmath> #inclu

UVA 11542 Square 高斯消元 异或方程组求解

题目链接:点击打开链接 白书的例题练练手. . . P161 #include <cstdio> #include <iostream> #include <algorithm> #include <math.h> #include <string.h> #include <algorithm> using namespace std; #define ll int #define LL long long const int mod

uva 11542 高斯消元

Square Input: Standard Input Output: Standard Output Given n integers you can generate 2n-1 non-empty subsets from them. Determine for how many of these subsets the product of all the integers in that is a perfect square. For example for the set {4,6

UVA 10023 - Square root(手算平方根)

题目:UVA 10023 - Square root(手算平方根) 题目链接 题目大意:求给定的一个数的平方根. 解题思路:用二分但是这个数太大了,就超时了.看题接后发现需要用一种手算平方根的算法. 算法: 先判断这个数是不是偶数位,是的话就第一次取前面的两位数,不是的话第一次就只取前面的一位数来作为被除数.接下来就是两位两位为一节来计算. 用前一次的计算结果乘上20+一个个位数a再乘上这个a,找到最大的a使得这个式子的结果不大于被除数. 被除数减去这个结果然后再在尾巴接上那个大数的接下来两位作

UVA 11461 Square Numbers解题报告

Discription A square number is an integer number whose square root is also an integer. For example 1, 4, 81 are some square numbers. Given two numbers a and b you will have to find out how many square numbers are there between a and b (inclusive). In

UVA - 10023 - Square root (模拟手算开方)

题目传送:UVA - 10023 思路:模拟手算开方,不想用c/c++,感觉太麻烦了,就直接用的java里的BigInteger类来写的,写了好久......Java还是得看看书呀,手算开方参考的这里 AC代码: import java.util.Scanner; import java.math.BigInteger; public class Main { static void fun(BigInteger x) { String str; str = x.toString(); str