Light OJ 1288 Subsets Forming Perfect Squares 高斯消元求矩阵的秩

题目来源:Light OJ 1288 Subsets Forming Perfect Squares

题意:给你n个数 选出一些数 他们的乘积是完全平方数 求有多少种方案

思路:每个数分解因子 每隔数可以选也可以不选 0 1表示 然后设有m种素数因子 选出的数组成的各个因子的数量必须是偶数

组成一个m行和n列的矩阵 每一行代表每一种因子的系数 解出自由元的数量

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 1010;
const int mod = 1000000007;
typedef int Matrix[maxn][maxn];
typedef long long LL;
int prime[maxn];
bool vis[maxn];

//返回a^p mod n 快速幂
LL pow_mod(LL a, LL p, LL n)
{
	LL ans = 1;
	while(p)
	{
		if(p&1)
		{
			ans *= a;
			ans %= n;
		}
		a *= a;
		a %= n;
		p >>= 1;
	}
	return ans;
}
void sieve(int n)
{
	int m = sqrt(n+0.5);
	memset(vis, 0, sizeof(vis));
	vis[0] = vis[1] = 1;
	for(int i = 2; i <= m; i++)
		if(!vis[i])
			for(int j = i*i; j <= n; j += i)
				vis[j] = 1;
}

int get_primes(int n)
{
	sieve(n);
	int c = 0;
	for(int i = 2; i <= n; i++)
		if(!vis[i])
			prime[c++] = i;
	return c;
}
int rank(Matrix A, int m, int n)
{
	int i = 0, j = 0, k, r, u;
	while(i < m && j < n)
	{
		r = i;
		for(k = i; k < m; k++)
			if(A[k][j])
			{
				r = k;
				break;
			}
		if(A[r][j])
		{
			if(r != i)
				for(k = 0; k <= n; k++)
					swap(A[r][k], A[i][k]);
			for(u = i+1; u < m; u++)
				if(A[u][j])
					for(k = i; k <= n; k++)
						A[u][k] ^= A[i][k];
			i++;
		}
		j++;
	}
	return i;
}
Matrix A;
int main()
{
	int cas = 1;
	int m = get_primes(500);
	int T;
	scanf("%d", &T);
	while(T--)
	{
		int n, maxp = 0;
		scanf("%d", &n);
		memset(A, 0, sizeof(A));
		for(int i = 0; i < n; i++)
		{
			long long x;
			scanf("%lld", &x);
			for(int j = 0; j < m; j++)
			{
				while(x % prime[j] == 0)
				{
					maxp = max(maxp, j);
					x /= prime[j];
					A[j][i] ^= 1;
				}
			}
		}
		int r = rank(A, maxp+1, n);
		printf("Case %d: %lld\n", cas++, pow_mod(2, n-r, mod)-1);
	}
	return 0;
}

Light OJ 1288 Subsets Forming Perfect Squares 高斯消元求矩阵的秩

时间: 2024-10-11 07:06:17

Light OJ 1288 Subsets Forming Perfect Squares 高斯消元求矩阵的秩的相关文章

POJ 开关问题 1830【高斯消元求矩阵的秩】

Language: Default 开关问题 Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 6656   Accepted: 2541 Description 有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关,如果为关就变为开.你的目标是经过若干次开关操作后使得最后N个开关达到一个特定的状态.对于任

hdu 2262 高斯消元求期望

Where is the canteen Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1070    Accepted Submission(s): 298 Problem Description After a long drastic struggle with himself, LL decide to go for some

高斯消元 求整数解模版

#include <iostream> #include <string.h> #include <cmath> using namespace std; const int maxn = 105; int equ, var; // 有equ个方程,var个变元.增广阵行数为equ, 分别为0到equ - 1,列数为var + 1,分别为0到var. int a[maxn][maxn]; int x[maxn]; // 解集. bool free_x[maxn]; //

hdu 3992 AC自动机上的高斯消元求期望

Crazy Typewriter Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 391    Accepted Submission(s): 109 Problem Description There was a crazy typewriter before. When the writer is not very sober, it

hdu 4418 高斯消元求期望

Time travel Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1480    Accepted Submission(s): 327 Problem Description Agent K is one of the greatest agents in a secret organization called Men in B

uva 10828 高斯消元求数学期望

Back to Kernighan-RitchieInput: Standard Input Output: Standard Output You must have heard the name of Kernighan and Ritchie, the authors of The C Programming Language. While coding in C, we use different control statements and loops, such as, if-the

HDU4870_Rating_双号从零单排_高斯消元求期望

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4870 原题: Rating Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 654    Accepted Submission(s): 415 Special Judge Problem Description A little gir

【bzoj2460】[BeiJing2011]元素 贪心+高斯消元求线性基

题目描述 相传,在远古时期,位于西方大陆的 Magic Land 上,人们已经掌握了用魔法矿石炼制法杖的技术.那时人们就认识到,一个法杖的法力取决于使用的矿石.一般地,矿石越多则法力越强,但物极必反:有时,人们为了获取更强的法力而使用了很多矿石,却在炼制过程中发现魔法矿石全部消失了,从而无法炼制出法杖,这个现象被称为“魔法抵消” .特别地,如果在炼制过程中使用超过一块同一种矿石,那么一定会发生“魔法抵消”. 后来,随着人们认知水平的提高,这个现象得到了很好的解释.经过了大量的实验后,著名法师 D

HDU5088Revenge of Nim II(高斯消元求自由变元个数)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5088 题意: 有n堆石头,可以去掉其中的一些堆(保证至少剩下一堆)问存不存在一种方法使第二个人赢: 分析: 这k个数边构成了一个01矩阵.那么能异或出0的充分条件是对这01矩阵高斯消元以后矩阵的秩小于矩阵的行数(也即存在一行全零,全零行就是异或出来的一行),那么我们只要对这个01矩阵高斯消元即可. 代码如下: #include<cstdio> #include<cstring> #in