• SGU 200 Cracking RSA (高斯消元)


    转载请注明出处,谢谢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。除去空集。。

    还要模拟一下高精度

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #define pb(a) push_back(a)
    #define mp(a,b) make_pair(a,b)
    using namespace std;
    const int N = 100;
    int t,m;
    int b[N];
    int a[N][N+1]={0};
    int prime[N],flag[N*11]={0},cnt=0;
    void Init(){
        for(int i=2;i<=1000;i++){
            if(flag[i]) continue;
            prime[cnt++]=i;
            if(cnt==t) return ;
            for(int j=2;j*i<=1000;j++)
                flag[i*j]=1;
        }
    }
    int gauss(int n,int m){
        int i,j;
        for(i=0,j=0;i<n&&j<m;j++){
            int k;
            for(k=i;k<n;k++)
                if(a[k][j])
                    break;
            if(k<n){
                for(int r=j;r<=m;r++)
                    swap(a[i][r],a[k][r]);
                for(int r=0;r<n;r++){
                    if(r!=i&&a[r][j]){
                        for(int t=j;t<=m;t++)
                            a[r][t]^=a[i][t];
                    }
                }
                i++;
            }
        }
        return m-i;
    }
    int ans[N];
    void out(){
        for(int i=ans[0];i>=1;i--)
            printf("%d",ans[i]);
        if(ans[0]==0) printf("0");
        printf("
    ");
    }
    void gao(){
        for(int i=1;i<=ans[0];i++){
            ans[i]*=2;
        }
        for(int p=1;p<=ans[0];p++){
            if(ans[p]>=10){
                ans[p]%=10;
                ans[p+1]++;
            }
        }
        if(ans[ans[0]+1]>0) ans[0]++;
    }
    void fuck(){
        ans[1]--;
        int p=1;
        while(ans[p]<0){
            ans[p]+=10;
            ans[++p]--;
        }
        if(ans[ans[0]]==0) ans[0]--;
    }
    int main(){
        scanf("%d%d",&t,&m);
        Init();
        for(int i=0;i<m;i++){
            scanf("%d",&b[i]);
            for(int j=0;j<t;j++){
                while(b[i]%prime[j]==0){
                    a[j][i]^=1;
                    b[i]/=prime[j];
                }
            }
        }
        int p=gauss(t,m);
        ans[0]=ans[1]=1;
        for(int i=1;i<=p;i++)
            gao();
        fuck();
        out();
        return 0;
    }
    


  • 相关阅读:
    TCP协议的三次握手、四次挥手
    .NET Framework 3.5 安装
    grep命令总结
    线性回归
    K-Mean聚类算法
    Logistic回归
    朴素贝叶斯
    Decision Tree
    KNN
    GCC for Win32开发环境介绍
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3206773.html
Copyright © 2020-2023  润新知