UVa11542
来源:互联网 发布:电竞椅 知乎 编辑:程序博客网 时间:2024/06/04 17:55
题目链接
分析:
题目特意说到,不含有超过500的素因子
这就是在提示我们可以质因数分解
我们把这n个数分解成若干素数乘积的形式,并用一个向量表示
如:4 6 10 15
这n=4个数中,涉及到的素数只有2,3,5这三个
分解后:
4=2^2*3^0*5^0 ——>{2,0,0}
6=2^1*3^1*5^0 ——>{1,1,0}
10=2^1*3^0*5^1 ——>{1,0,1}
15=2^0*3^1*5^1 ——>{0,1,1}
我们现在按照题目要求,选出若干数乘起来,
得到的数字(我们称为W)也一定可以用2,3,5这三个质数表示
为了辅助该数的表示,我们设一个01向量x
xi表示第i位数字是否要选(选是1,不选是0)
这样我们按照题目求出的数就可以如下表示了:
因为只有第一个数(4),第二个数(6),第三个数(10)有2这个因子,
所以得到的W中2的指数只能由这三个数决定,其余的同理
如果W可以被开方,显然每个质数的次数都要是偶数,即
x2+x3=0 (mod 2)
x2+x4=0 (mod 2)
x3+x4=0 (mod 2)
由于异或和数字的奇偶性有很大关系,所以上述的方程组可以变成异或方程
x2 XOR x3=0
x2 XOR x4=0
x3 XOR x4=0
这样我们就可用高斯消元优美的解决了
最后的答案是
2^(自由元的个数)-1
因为每个自由元都有两种选择,但是题目不允许我们一个都不选,所以要-1
tip
在阵式的构造上,
a[i][j]=1表示第j个数字有第i个质数这个因子,且该因子在第j个数中的次数是奇数,
换句换说就是,第i个质数的次数会受到第j个数的影响
gauss消元没有固定的模板,重要的是掌握ta的思维方式
//这里写代码片#include<cstdio>#include<cstring>#include<iostream>#define ll long longusing namespace std;int a[102][102]; //500以内的素数只有95个 int sshu[102],tot=0,maxp,n; bool no[502];void prime(int n){ for (int i=2;i<=n;i++) { if (!no[i]) sshu[++tot]=i; for (int j=1;j<=tot&&sshu[j]*i<=n;j++) { no[sshu[j]*i]=1; if (i%sshu[j]==0) break; } }}int gauss(int n,int m) //n个未知量,m个方程 { int cnt=0; int now=1; for (int i=1;i<=n;i++) //枚举未知量 { int num=now; //消元消到了第几个方程 for (int j=now;j<=m;j++) if (a[j][i]) { num=j; break; } if (!a[num][i]) continue; if (now!=num) for (int j=1;j<=n+1;j++) swap(a[now][j],a[num][j]); for (int j=1;j<=m;j++) if (a[j][i]&&j!=now) for (int k=1;k<=n+1;k++) a[j][k]^=a[now][k]; now++; } return n-now+1;}int main(){ prime(500); int T; scanf("%d",&T); while (T--) { memset(a,0,sizeof(a)); scanf("%d",&n); ll x; //注意x的范围 maxp=0; //n个数中涉及到的最大素数 for (int i=1;i<=n;i++) { scanf("%lld",&x); for (int j=1;j<=tot&&x!=1;j++) while (x%sshu[j]==0) { a[j][i]^=1; //sshu[j]的系数可能有第i个数的影响 x/=sshu[j]; maxp=max(maxp,j); } } int ans=gauss(n,maxp); printf("%lld\n",(1LL<<ans)-1); } return 0;}
- UVa11542
- uva11542 Square
- uva11542(高斯消元)
- uva11542 Square
- 【高斯消元】UVA11542
- [UVA11542] Square 高斯消元
- 【UVA11542】Square(高斯消元)
- Uva11542 求矩阵的秩
- uva11542 Square(异或方程组)
- MySQL Daemon failed to start. 无法启动
- 浅谈EABI和OABI
- 深度学习 激活函数
- HDU
- [HNOI2008]水平可见直线
- UVa11542
- KMP算法
- SSD算法的MXNet实现
- 36、在C#项目中使用Dapper
- C语言查看BMP格式图片头(bmpHeader.c)
- 为什么hive中show tables没有表和在mysql中use hive后再show tables却能看见表?
- 【c基础知识】#ifdef 条件编译的巧妙用法
- 并发登录人数控制——shiro
- UnicodeEncodeError: 'latin-1' codec can't encode characters in position 44-46: ordinal not in range(