HDU 5833 Zhu and 772002 高斯消元解异或方程组,求自由元个数,bitset压位
来源:互联网 发布:淘宝上牛仔裤 编辑:程序博客网 时间:2024/06/07 08:46
Zhu and 772002
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1799 Accepted Submission(s): 624
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.
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).
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.
Sample Input
2
3
3 3 4
3
2 2 2
Sample Output
Case #1:
3
Case #2:
3
解题方法: 白书原题,看这位小哥的吧。见这里
//HDU 5833 XOR GUASS#include <bits/stdc++.h>using namespace std;const int maxn = 2010;typedef long long LL;typedef int Matrix[maxn][maxn];const int mod = 1000000007;Matrix A; //A[i][j]就表示第j个数的这个i素数是奇数还是偶数int n, vis[2010], prime[2010];int pre_deal(int m){ memset(vis, 0, sizeof(vis)); int cnt = 0; for(int i = 2; i < m; i++){ if(!vis[i]){ prime[cnt++] = i; for(int j = i*i; j < m; j += i){ vis[j] = 1; } } } return cnt;}LL powmod(LL a, LL n){ LL res = 1; while(n){ if(n&1) res = res*a%mod; a = a*a%mod; n >>= 1; } return res;}int xor_guass(int m, int n) //A是异或方程组系数矩阵 返回秩{ int i = 0, j = 0, k, r, u; while(i < m && j < n){//当前正在处理第i个方程,第j个变量 r = i; for(int 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]); //消元完成之后第i行的第一个非0列是第j列,且第u>i行的第j列全是0 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(){ int tot = pre_deal(maxn); int T, ks = 0; scanf("%d", &T); while(T--){ memset(A, 0, sizeof(A)); scanf("%d", &n); int maxp = 0; for(int i = 0; i < n; i++){ LL x; scanf("%lld", &x); for(int j = 0; j < tot; j++){ while(x % prime[j] == 0){ maxp = max(maxp, j); x /= prime[j]; A[j][i] ^= 1; } } } int rr = xor_guass(maxp + 1, n);//秩 printf("Case #%d:\n", ++ks); printf("%lld\n", powmod(2, n - rr) - 1); } return 0;}
当然我们不能这样A了就算了,在大白树上提到了一种bitset优化的方法,即是bitset压位优化。即是把32列合并到一个无符号32位整数中,然后只需要用一次逐位异或xor就可以处理32列了,所以复杂度可以降到O(n*n*n/32),扣扣常数还是非常支持的。
//HDU 5833 XOR GUASS bitset#include <bits/stdc++.h>using namespace std;const int maxn = 2005;const int mod = 1e9+7;int n, vis[maxn], prime[maxn], cnt;void pre_deal(){ for(int i = 2; i < maxn; i++){ if(vis[i]) continue; prime[cnt++] = i; for(int j = i; j < maxn; j += i) vis[j] = 1; }}bitset <330> A[305]; //A[i][j]就表示第j个数的这个i素数是奇数还是偶数int main(){ pre_deal(); int T, ks = 0; scanf("%d", &T); while(T--){ printf("Case #%d:\n", ++ks); for(int i = 0; i < 305; i++) A[i].reset(); scanf("%d", &n); for(int i = 0; i < n; i++){ long long x; scanf("%lld", &x); for(int j = 0; j < cnt; j++){ if(x%prime[j] == 0){ int flag = 0; while(x%prime[j] == 0){ x /= prime[j]; flag ^= 1; } A[j][i] = flag; } } } int i = 0, j = 0; //xor消元之后j就是秩 for(i = 0; i < n; i++){ int id = -1; for(int k = j; k < cnt; k++){ if(A[k][i]){ id = k; break; } } if(id == -1) continue; swap(A[j], A[id]); for(int k = j + 1; k < cnt; k++){ if(A[k][i]) A[k] ^= A[j]; } j++; } int ans = 1; for(int i = 0; i < n - j; i++) ans = ans * 2 % mod; ans--; printf("%d\n", ans); } return 0;}
所以一下午只写了2个高斯消元??效率需要挺高啦。
- HDU 5833 Zhu and 772002 高斯消元解异或方程组,求自由元个数,bitset压位
- Hdu 5833 Zhu and 772002(高斯消元解异或方程组)
- [hdu 5833 Zhu and 772002] 高斯消元求异或方程组
- 【HDU 5833】【异或方程组高斯消元】Zhu and 772002
- HDU 5833 Zhu and 772002(异或方程组高斯消元)
- Hdu 5833 Zhu and 772002 异或方程组高斯消元
- hdu5833 Zhu and 772002 【高斯消元解异或方程组】
- ACM高斯消元法 亦或方程组求秩 (HDU5833 Zhu and 772002)
- HDU - 5833 Zhu and 772002(高斯消元解异或方程)
- HDU-5833 Zhu and 772002(异或方程高斯消元)
- HDU 5833 Zhu and 772002
- HDU 5833 Zhu and 772002
- HDU 5833 Zhu and 772002
- hdu 5833 Zhu and 772002
- HDU-5833-Zhu and 772002
- Zhu and 772002 HDU
- Zhu and 772002 HDU
- HDU5833(2016CCPC网赛)——Zhu and 772002(异或方程组,素数分解)
- Spring_AOP_XML
- 观察者模式 —— 让你的对象知悉现况
- hadoop2.5.2学习14--MR之协同过滤天猫推荐算法实现01
- 线程的调度和优先级问题
- Java数据结构04 栈与队列
- HDU 5833 Zhu and 772002 高斯消元解异或方程组,求自由元个数,bitset压位
- JavaScript匿名自执行函数的用处
- android CoordinatorLayout使用
- ubuntu 执行apt-get update报错Failed to fetch
- 关于 Java 面试的总结
- 深入简出的ngin
- 对象存储和块存储的区别
- 都钻进我的裙下了,当然会看到奇♂怪の东西啦~\(≧▽≦)/~
- KNN算法及其实现