2016ccpc 1002(hdu5833)题解 (高斯消元求异或方程组自由变元)
来源:互联网 发布:虚拟机安装教程mac 编辑:程序博客网 时间:2024/05/18 02:22
比赛结束才知道是个高斯消元的题目,吓得我赶紧学了一发,然后惊讶的发现白皮书上原题QAQ.
由于刚学会,虽然是手敲但有些细节还是比对了模板,所以并不能解释,先放一发代码,等熟练了再补.
-------------------------------------分割线---------------------------------------------
时隔两个月终于有时间和精力来把这题来理一理了。
这个题比较重要的一点是想到把每个数分解成素数的幂次,这样的话, 每个数相乘的结果,只要每个素数的幂都是偶数,就能保证乘积是平方数了。
所以把每个数分解,列出每个数在所有可能的素因子的幂的加和,要求结果为偶数,这样的话等价于每一项都对2取模,每个等式右边要求结果都为0。
如果能分解成n个素因子,那么就有n个等式,每个等式等于号左边是每个数在这个素因子上的幂对2取模,等式右边为0.
现在求有几种组合能使乘积为平方数,即线性方程组有多少个解,那么简单了,只需要求出自由变元数量ans,2的ans次-1即答案,因为题目要求不能一个数都不取,所以需要减去都为0的情况。求自用变元就是高斯消元模板了,在代码里介绍吧。
代码:
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cstdlib>using namespace std;int prim[400];int v[2005];long long x[400];int a[400][400];int k;const int mod=1000000007;void pri(int maxn){ int i, j; for(i=2; i<=maxn; i++) { if(!v[i]) { prim[k++]=i; for(j=i; j<=maxn; j+=i) { v[j]=0; v[j]=1; } } }}long long quick_mod(int m, long long n){ long long ret=1; long long term=m; while(n>0) { if(n%2==1)ret=(ret*term)%mod; n>>=1; term=(term*term)%mod; } return ret;}int gauss(int var, int equ){ int i, j; int col, maxr; int k=0; for(k=0, col=0; k<equ && col<var; k++, col++) { maxr=k; for(i=k; i<equ; i++) { if(abs(a[i][col])>abs(a[maxr][col]))maxr=i; //找到这一列最大的那个数,用于消去这一列以下的数,这里为1即可 } if(a[maxr][col]==0) //如果这一列已经都为0,继续对当前的行操作 { k--; continue; } for(j=col; j<var+1; j++) { swap(a[k][j], a[maxr][j]); //将选出的这一列最大的数对应的行交换到k行 } for(i=k+1; i<equ; i++) { if(a[i][col]!=0) for(j=col; j<var+1; j++) { { a[i][j]^=a[k][j]; // 消去col的1 } } } } for(i=k; i<equ; i++) { if(a[i][col]!=0)return -1; } if(var>k)return var-k; //变元数减去秩即自由变元数 return 0;}int main(){ int t; pri(2000); scanf("%d", &t); int e=1; while(t--) { int n; scanf("%d", &n); int i, j; memset(a,0,sizeof(a)); for(i=0; i<n; i++) { scanf("%lld", &x[i]); } for(i=0; i<n; i++) { for(j=0; j<k; j++) { int c=0; while(x[i]%prim[j]==0) { x[i]/=prim[j]; c++; } if(c&1) a[j][i]=1; } } long long ans=gauss(n, k); printf("Case #%d:\n", e++); printf("%lld\n", quick_mod(2,ans)-1); } return 0;}
0 0
- 2016ccpc 1002(hdu5833)题解 (高斯消元求异或方程组自由变元)
- HDU5833(2016CCPC网赛)——Zhu and 772002(异或方程组,素数分解)
- hdu5833 Zhu and 772002 【高斯消元解异或方程组】
- HDU 5833 Zhu and 772002 高斯消元解异或方程组,求自由元个数,bitset压位
- ACM高斯消元法 亦或方程组求秩 (HDU5833 Zhu and 772002)
- hdu5833 异或版高斯消元
- Ural1042(高斯消元+枚举自由变元)
- HDOJ Lanterns 3364【高斯消元求自由变元】
- POJ3185 高斯消元 +枚举自由变元
- 高斯消元法解01异或方程组(附poj 1222题解)
- HDU5833
- HDU5088Revenge of Nim II(高斯消元求自由变元个数)
- sgu200:Cracking RSA(模意义下高斯消元求自由变元个数)
- POJ 1753 Flip Game(高斯消元法,枚举自由变元)
- POJ 3185 The Water Bowls(高斯消元法,枚举自由变元)
- poj 1830 开关问题 【高斯消元 求解自由变元数目】
- poj 3185 The Water Bowls 【高斯消元 + 枚举自由变元】
- poj 1681 Painter's Problem 高斯消元 枚举自由变元
- eclipse中全局替换
- 欧拉图
- 小米运维—互联网企业级监控系统实践
- bzoj1082[SCOI2005]栅栏
- 关于宗海图84与2000坐标差别的困惑
- 2016ccpc 1002(hdu5833)题解 (高斯消元求异或方程组自由变元)
- windows7 vs2010 编译winpcap
- [leetcode] 385. Mini Parser
- 知识点:01背包(多种姿势:二维实现+一维实现+滚动数组实现+背包装满+输出最优方案)
- PHP empty、isset、isnull的区别
- 最优间隔分类器.原始/对偶优化问题.KKT.SVM对偶
- HDU 5839 Special Tetrahedron
- bzoj1801(递推)
- poj 1384 Piggy-Bank(完全背包)