HDU 5833 Zhu and 772002
Zhu and 772002
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 542 Accepted Submission(s): 180
Problem Description
Zhu and 772002 are both good at math. One day, Zhu wants to test the ability of 772002, so he asks 772002 to solve a math problem.
But 772002 has a appointment with his girl friend. So 772002 gives this problem to you.
There are n numbers a1,a2,...,an. The value of the prime factors of each number does not exceed 2000, you can choose at least one number and multiply them, then you can get a number b.
How many different ways of choices can make b is a perfect square number. The answer maybe too large, so you should output the answer modulo by 1000000007.
But 772002 has a appointment with his girl friend. So 772002 gives this problem to you.
There are n numbers a1,a2,...,an. The value of the prime factors of each number does not exceed 2000, you can choose at least one number and multiply them, then you can get a number b.
How many different ways of choices can make b is a perfect square number. The answer maybe too large, so you should output the answer modulo by 1000000007.
Input
First line is a positive integer T , represents there are T test cases.
For each test case:
First line includes a number n(1≤n≤300),next line there are n numbers a1,a2,...,an,(1≤ai≤1018).
For each test case:
First line includes a number n(1≤n≤300),next line there are n numbers a1,a2,...,an,(1≤ai≤1018).
Output
For the i-th test case , first output Case #i: in a single line.
Then output the answer of i-th test case modulo by 1000000007.
Then output the answer of i-th test case modulo by 1000000007.
Sample Input
2
3
3 3 4
3
2 2 2
Sample Output
Case #1:
3
Case #2:
3
白书160页写的已经很详细了.
比如 4,6,20这3个数。
先把他们分解质因数。4=2*2,6=2*3,20=2*2*5
设未知数 x1 x2 x3 x1表示取不取4这个数 取得话 x1=1 ,不取x1=0 同理x2、x3
那么 最终选取的几个数的乘积为 2^(2*x1+x2+2*x3)*3^(x2)*5^(x3)
那么 结果是不是完全平方数取决于
(1) 2*x1+x2+2*x3、
(2)x2、
(3)x3
的奇偶性。
显然,(1)(2)(3)都应该是偶数
我们可以用高斯消元解决这个问题。可以得到下面的增广矩阵
x1 x2 x3
2 1 2 0
0 1 0 0
0 0 1 0
其中2 和0是等价的
进而得到
0 1 0 0
0 0 1 0
0 0 0 0
变元只有一个 线性代数好的都知道 自由变元个数=n-R(A) R(A)是矩阵的秩,就是化为阶梯矩阵后非零行的行数 n是未知数的个数
答案就是2^1-1=1
/* *********************************************** Author :guanjun Created Time :2016/8/15 13:56:49 File Name :hdu5833.cpp ************************************************ */ #include <iostream> #include <cstring> #include <cstdlib> #include <stdio.h> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <iomanip> #include <list> #include <deque> #include <stack> #define ull unsigned long long #define ll long long #define mod 1000000007 #define INF 0x3f3f3f3f #define maxn 10010 #define cle(a) memset(a,0,sizeof(a)) const ull inf = 1LL << 61; const double eps=1e-5; using namespace std; int prime[2100]; int vis[2100]; void init(){ int cnt=0; cle(vis); for(int i=2;i<2100;i++){ if(!vis[i]){ prime[cnt++]=i; for(int j=i;j<2100;j+=i){ vis[j]=1; } } } //cout<<cnt<<endl; } int A[310][310];//系数矩阵 int gauss(int m,int n){//m个方程 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; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif //freopen("out.txt","w",stdout); init(); int T; cin>>T; for(int t=1;t<=T;t++){ int n,maxp=0; ll x; scanf("%d",&n); cle(A); for(int i=0;i<n;i++){ scanf("%lld",&x); for(int j=0;j<303;j++){ while(x%prime[j]==0){ maxp=max(maxp,j); x/=prime[j]; A[j][i]^=1; } } } int r=gauss(maxp+1,n); ll ans=1LL; for(int i=0;i<n-r;i++){ ans*=2LL; ans%=mod; } printf("Case #%d:\n%lld\n",t,ans-1); } return 0; }
另一种板子
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define int long long const int N = 330; const int Mod =1e9+7; int primeCount, n, primes[N], a[N]; bool coefficient[N][N]; bool isPrime(int n) { if (n < 2) { return false; } for (int i = 2; i * i <= n; ++ i) { if (n % i == 0) { return false; } } return true; } int getExponent(int p, int n) { int result = 0; while (n % p == 0) { result ++; n /= p; } return result; } int countFree(int n, int m) { int result = 0; int baseCount = 0; for (int j = 0; j < m; ++ j) { int pivot = baseCount; while (pivot < n && !coefficient[pivot][j]) { pivot ++; } if (pivot >= n) { result ++; } else { for (int k = 0; k < m; ++ k) { swap(coefficient[baseCount][k], coefficient[pivot][k]); } for (int i = 0; i < n; ++ i) { if (i != baseCount && coefficient[i][j]) { for (int k = 0; k < m; ++ k) { coefficient[i][k] ^= coefficient[baseCount][k]; } } } baseCount ++; } } return result; } const int M = 100; struct BigInteger { int length, digit[M]; BigInteger(int n = 0): length(0) { memset(digit, 0, sizeof(digit)); while (n > 0) { digit[length ++] = n % 10; n /= 10; } } int &operator[](int i) { return digit[i]; } int operator[](int i) const { return digit[i]; } void show() { int cmp=0; for(int i=length-1;i>=0;i--){ cmp=(cmp*10+digit[i]); if(cmp>=Mod)cmp%=Mod; } printf("%I64d\n",cmp); } }; BigInteger operator *(const BigInteger &a, int b) { BigInteger c; int delta = 0; for (int i = 0; i <= a.length; ++ i) { delta += a[i] * b; c[i] = delta % 10; delta /= 10; } c.length = a.length + 1; while (c.length > 0 && c[c.length - 1] == 0) { c.length --; } return c; } main() { //freopen("in.txt","r",stdin); int T; scanf("%I64d",&T); for(int ca=1;ca<=T;ca++){ primeCount = 303; scanf("%I64d", &n); for (int i = 0; i < n; ++ i) { scanf("%I64d", a + i); } for (int i = 0, p = 2; i < primeCount; ++ i) { while (!isPrime(p)) { p ++; } primes[i] = p ++; } for (int i = 0; i < primeCount; ++ i) { for (int j = 0; j < n; ++ j) { coefficient[i][j] = (getExponent(primes[i], a[j]) & 1) == 1; } } int freeCount = countFree(primeCount, n); BigInteger result(1); for (int i = 0; i < freeCount; ++ i) { result = result * 2; } result[0] --; printf("Case #%I64d:\n",ca); result.show(); } }
之前 贴错代码了..
原文地址:http://www.cnblogs.com/pk28/
与有肝胆人共事,从无字句处读书。
欢迎关注公众号:
欢迎关注公众号: