题目地址:SGU 200
这题居然还考大数高精度。。无语。。
令有该因子偶数个为0,奇数个为1,这样就满足异或运算了,即奇+奇=偶,偶+偶=偶,奇+偶=奇。然后建立方程高斯消元求变元个数free_num,那么子集的个数就是2^free_num-1。减1是去掉0的情况。注意要用大数运算
代码如下:
#include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include <stdio.h> using namespace std; #define LL __int64 #define pi acos(-1.0) const int mod=1e9+7; const int INF=1e9; const double eqs=1e-9; int mat[120][120], a[120], equ, var, prime[120]; int c[100]; int gauss() { int i, j, k, h, max_r, tmp; for(i=0,j=0;i<equ&&j<var;i++,j++){ max_r=i; for(k=i+1;k<equ;k++){ if(mat[k][j]>mat[max_r][j]) max_r=k; } if(max_r!=i){ for(k=j;k<=var;k++){ swap(mat[i][k],mat[max_r][k]); } } if(mat[i][j]==0){ i--; continue ; } for(k=i+1;k<equ;k++){ if(mat[k][j]==0) continue ; for(h=j;h<=var;h++){ mat[k][h]^=mat[i][h]; } } } tmp=i; //printf("%d\n",tmp); for(;i<equ;i++){ if(mat[i][var]){ return 0; } } return var-tmp; } void output(int k) { int i, j, x, y, tmp; memset(c,0,sizeof(c)); c[0]=1; x=0; for(i=0;i<k;i++){ for(j=0;j<=80;j++){ y=(c[j]*2+x)%10; x=(c[j]*2+x)/10; c[j]=y; } } for(i=80;i>=0;i--){ if(c[i]){ tmp=i; break; } } c[0]--; for(i=tmp;i>=0;i--){ printf("%d",c[i]); } puts(""); } void init() { int i, j, cnt=0, flag; for(i=2;;i++){ flag=0; for(j=2;j*j<=i;j++){ if(i%j==0){ flag=1; break; } } if(!flag){ prime[cnt++]=i; } if(cnt==100) return ; } } int main() { int t, n, i, j, x, cnt, ans; init(); scanf("%d%d",&t,&n); for(i=0; i<n; i++) { scanf("%d",&a[i]); } for(i=0; i<n; i++) { x=a[i]; for(j=0;j<t;j++){ cnt=0; while(x%prime[j]==0){ cnt++; x/=prime[j]; } mat[j][i]=(cnt&1); } } for(i=0;i<t;i++){ mat[i][n]=0; } equ=t; var=n; ans=gauss(); if(ans) output(ans); else puts("0"); return 0; }
SGU 200 Cracking RSA (高斯消元+大数高精度)
原文地址:http://blog.csdn.net/scf0920/article/details/43303553