SGU 200 Cracking RSA (高斯消元)

 
分类: ACM_数学类   90人阅读  评论(0)  收藏  举报

转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 

题意:给出m个整理,因子全部为前t个素数。问有多少个子集,乘积是平方数

http://acm.sgu.ru/problem.php?contest=0&problem=200 

做法:列方程组,a1,a2,a3……am分别表示bi是否在集合中。对于每一个素因子,建立异或方程组,要求因子个数为偶数,即异或为0。

子集个数便是解的个数,高斯消元后求出变元个数num,结果是2^ num-1。除去空集。。

还要模拟一下高精度

[cpp]  view plain copy
  1. #include <iostream>  
  2. #include <cstdio>  
  3. #include <cstring>  
  4. #include <algorithm>  
  5. #include <cmath>  
  6. #include <vector>  
  7. #include <set>  
  8. #include <map>  
  9. #include <queue>  
  10. #define pb(a) push_back(a)  
  11. #define mp(a,b) make_pair(a,b)  
  12. using namespace std;  
  13. const int N = 100;  
  14. int t,m;  
  15. int b[N];  
  16. int a[N][N+1]={0};  
  17. int prime[N],flag[N*11]={0},cnt=0;  
  18. void Init(){  
  19.     for(int i=2;i<=1000;i++){  
  20.         if(flag[i]) continue;  
  21.         prime[cnt++]=i;  
  22.         if(cnt==t) return ;  
  23.         for(int j=2;j*i<=1000;j++)  
  24.             flag[i*j]=1;  
  25.     }  
  26. }  
  27. int gauss(int n,int m){  
  28.     int i,j;  
  29.     for(i=0,j=0;i<n&&j<m;j++){  
  30.         int k;  
  31.         for(k=i;k<n;k++)  
  32.             if(a[k][j])  
  33.                 break;  
  34.         if(k<n){  
  35.             for(int r=j;r<=m;r++)  
  36.                 swap(a[i][r],a[k][r]);  
  37.             for(int r=0;r<n;r++){  
  38.                 if(r!=i&&a[r][j]){  
  39.                     for(int t=j;t<=m;t++)  
  40.                         a[r][t]^=a[i][t];  
  41.                 }  
  42.             }  
  43.             i++;  
  44.         }  
  45.     }  
  46.     return m-i;  
  47. }  
  48. int ans[N];  
  49. void out(){  
  50.     for(int i=ans[0];i>=1;i--)  
  51.         printf("%d",ans[i]);  
  52.     if(ans[0]==0) printf("0");  
  53.     printf("\n");  
  54. }  
  55. void gao(){  
  56.     for(int i=1;i<=ans[0];i++){  
  57.         ans[i]*=2;  
  58.     }  
  59.     for(int p=1;p<=ans[0];p++){  
  60.         if(ans[p]>=10){  
  61.             ans[p]%=10;  
  62.             ans[p+1]++;  
  63.         }  
  64.     }  
  65.     if(ans[ans[0]+1]>0) ans[0]++;  
  66. }  
  67. void fuck(){  
  68.     ans[1]--;  
  69.     int p=1;  
  70.     while(ans[p]<0){  
  71.         ans[p]+=10;  
  72.         ans[++p]--;  
  73.     }  
  74.     if(ans[ans[0]]==0) ans[0]--;  
  75. }  
  76. int main(){  
  77.     scanf("%d%d",&t,&m);  
  78.     Init();  
  79.     for(int i=0;i<m;i++){  
  80.         scanf("%d",&b[i]);  
  81.         for(int j=0;j<t;j++){  
  82.             while(b[i]%prime[j]==0){  
  83.                 a[j][i]^=1;  
  84.                 b[i]/=prime[j];  
  85.             }  
  86.         }  
  87.     }  
  88.     int p=gauss(t,m);  
  89.     ans[0]=ans[1]=1;  
  90.     for(int i=1;i<=p;i++)  
  91.         gao();  
  92.     fuck();  
  93.     out();  
  94.     return 0;  
  95. }  

你可能感兴趣的:(ACM_数学类)