题意:
给出n个数的集合,这n个数的因子都是前t个质数。求这个集合有多少个子集,这个子集满足元素相乘是平方数。
题解:
高斯消元。因为都是质数,那么要得到平方数那么这些集合的元素对应的因子要成对出现,不成对不可能够成完全平方数。于是每个方程代表一个因子,设xi表示集合i元素是否有,然后列出t个式子求解。最后只要求2^(自由因子个数)。
#include<iostream> #include<math.h> #include<stdio.h> #include<algorithm> #include<string.h> #include<vector> #include<queue> #include<map> #include<set> using namespace std; #define B(x) (1<<(x)) void cmax(int& a,int b){ if(b>a)a=b; } void cmin(int& a,int b){ if(b<a)a=b; } typedef long long ll; const int oo=0x3f3f3f3f; const ll OO=1LL<<61; const int MOD=10007; const int maxn=105; const int maxm=105; int maze[maxn][maxn]; int a[maxn],p[1005]; #define eps 1e-8 struct BigInt{ int num[maxm]; BigInt(){ memset(num,0,sizeof num); } BigInt(int a){ for(int i=0;i<maxm;i++){ num[i]=a%10; a/=10; } } BigInt operator+(const BigInt& a)const{ BigInt b; int x=0,g=0; for(int i=0;i<maxn;i++){ x=g+a.num[i]+num[i]; b.num[i]=x%10; g=x/10; } return b; } BigInt operator*(int t)const{ BigInt a; int x=0,g=0; for(int i=0;i<maxm;i++){ x=g+num[i]*t; a.num[i]=x%10; g=x/10; } return a; } void sub_one(){ for(int i=0;i<maxm;i++){ if(num[i]>0){ num[i]--; break; } } } void output(){ int i; for(i=maxm-1;i>=0&&num[i]==0;i--); for(;i>=0;i--)printf("%d",num[i]); puts(""); } }pow2[maxm]; int Gauss(int n,int m){ int r,c; for(r=c=0;r<n&&c<m;r++,c++){ int id=r; for(int i=r+1;i<n;i++){ if(maze[i][c]>maze[id][c]) id=i; } if(id!=r){ for(int j=c;j<=m;j++){ swap(maze[r][j],maze[id][j]); } } if(maze[r][c]==0){ r--; continue; } for(int i=r+1;i<n;i++){ if(maze[i][c]!=0){ for(int j=c;j<=m;j++){ maze[i][j]^=maze[r][j]; } } } } return m-r; } void getPrime() { memset(p,0,sizeof p); for(int i=2;i<=1000;i++) { if(!p[i])p[++p[0]]=i; for(int j=1;j<=p[0]&&p[j]*i<=1000;j++) { p[p[j]*i]=1; if(i%p[j]==0)break; } } } void Init(){ pow2[0]=1; for(int i=1;i<maxm;i++){ pow2[i]=pow2[i-1]*2; } getPrime(); } int main(){ //freopen("G:\\read.txt","r",stdin); int t,n; Init(); while(scanf("%d %d",&t,&n)!=EOF){ for(int i=0;i<n;i++){ scanf("%d",&a[i]); } memset(maze,0,sizeof maze); for(int i=0;i<t;i++){ for(int j=0;j<n;j++){ while(a[j]%p[i+1]==0){ maze[i][j]^=1; a[j]/=p[i+1]; } } } int id=Gauss(t,n); BigInt ans=pow2[id]; ans.sub_one(); ans.output(); } return 0; } /** */