首页 > 代码库 > SGU 200 Cracking RSA (高斯消元+大数高精度)

SGU 200 Cracking RSA (高斯消元+大数高精度)

题目地址: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 (高斯消元+大数高精度)