zoukankan      html  css  js  c++  java
  • SGU 200. Cracking RSA(高斯消元+高精度)

    标题效果:鉴于m整数,之前存在的所有因素t素数。问:有多少子集。他们的产品是数量的平方。

    解题思路:

    全然平方数就是要求每一个质因子的指数是偶数次。
    对每一个质因子建立一个方程。

    变成模2的线性方程组。
    求解这个方程组有多少个自由变元。答案就是 2^p - 1 。(-1是去掉空集的情况)

    注意因为2^p会超出数据范围所以还须要用高精度算法。

    200. Cracking RSA

    time limit per test: 0.25 sec.
    memory limit per test: 65536 KB
    input: standard
    output: standard



    The following problem is somehow related to the final stage of many famous integer factorization algorithms involved in some cryptoanalytical problems, for example cracking well-known RSA public key system. 

    The most powerful of such algorithms, so called quadratic sieve descendant algorithms, utilize the fact that if n = pq where p and q are large unknown primes needed to be found out, then if v2=w2(mod n), u ≠ v (mod n) and u ≠ -v (mod n), then gcd(v + w, n) is a factor of n (either p or q). 

    Not getting further in the details of these algorithms, let us consider our problem. Given m integer numbers b1, b2, ..., bm such that all their prime factors are from the set of first t primes, the task is to find such a subset S of {1, 2, ..., m} that product of bi for i from S is a perfect square i.e. equal to u2 for some integer u. Given such S we get one pair for testing (product of S elements stands for v when w is known from other steps of algorithms which are of no interest to us, testing performed is checking whether pair is nontrivial, i.e. u ≠ v (mod n) and u ≠ -v (mod n)). Since we want to factor n with maximum possible probability, we would like to get as many such sets as possible. So the interesting problem could be to calculate the number of all such sets. This is exactly your task. 

    Input

    The first line of the input file contains two integers t and m (1 ≤ t ≤ 100, 1 ≤ m ≤ 100). The second line of the input file contains m integer numbers bi such that all their prime factors are from t first primes (for example, if t = 3 all their prime factors are from the set {2, 3, 5}). 1 ≤ bi ≤ 109 for all i. 

    Output

    Output the number of non-empty subsets of the given set {bi}, the product of numbers from which is a perfect square 


    Sample test(s)

    Input
    
    
    3 4 9 20 500 3 
    Output
    
    


    #include <algorithm>
    #include <iostream>
    #include <stdlib.h>
    #include <string.h>
    #include <iomanip>
    #include <stdio.h>
    #include <string>
    #include <queue>
    #include <cmath>
    #include <stack>
    #include <map>
    #include <set>
    #define eps 1e-10
    ///#define M 1000100
    #define LL __int64
    ///#define LL long long
    ///#define INF 0x7ffffff
    #define INF 0x3f3f3f3f
    #define PI 3.1415926535898
    #define zero(x) ((fabs(x)<eps)?0:x)
    
    const int maxn = 210;
    
    using namespace std;
    
    bool f[maxn+1000];
    int k[maxn+1000];
    int a[maxn][maxn];
    int num[maxn];
    int equ, var;
    char str1[maxn], str2[maxn];
    
    void Add(char a[], char b[], char c[])
    {
        int len1 = strlen(a);
        int len2 = strlen(b);
        int n = max(len1, len2);
        int add = 0;
        for(int i = 0; i < n; i++)
        {
            int cnt = 0;
            if(i < len1) cnt += a[i]-'0';
            if(i < len2) cnt += b[i]-'0';
            cnt += add;
            add = cnt/10;
            c[i] = cnt%10+'0';
        }
        if(add) c[n++] = add+'0';
        c[n] = 0;
    }
    
    void Sub_1(char a[])
    {
        int s = 0;
        while(a[s] == '0') s++;
        a[s]--;
        for(int i = 0; i < s; i++)
            a[i] = '9';
        int len = strlen(a);
        while(len > 1 && a[len-1] == '0') len--;
        a[len] = 0;
    }
    
    void Prime()
    {
        int t = 0;
        memset(f, false, sizeof(f));
        for(int i = 2; i <= 1005; i++)
        {
            if(!f[i])
                k[t++] = i;
            for(int j = 0; j < t; j++)
            {
                if(i*k[j] > 1005)
                    break;
                f[i*k[j]] = true;
                if(i%k[j] == 0)
                    break;
            }
        }
    }
    
    int Gauss()
    {
        int row, col;
        int max_r;
        row = col = 0;
        while(row < equ && col < var)
        {
            max_r = row;
            for(int i = row+1; i < equ; i++)
            {
                if(a[i][col]) max_r = i;
            }
            if(a[max_r][col] == 0)
            {
                col++;
                continue;
            }
            if(max_r != row)
            {
                for(int j = col; j <= var; j++) swap(a[max_r][j], a[row][j]);
            }
            for(int i = row+1; i < equ; i++)
            {
                if(a[i][col] == 0) continue;
                for(int j = col; j <= var; j++) a[i][j] ^= a[row][j];
            }
            col++;
            row++;
        }
        return var-row;
    }
    
    int main()
    {
        Prime();
        int n, m;
        while(cin >>n>>m)
        {
            memset(a, 0, sizeof(a));
            for(int i = 0; i < m; i++) cin >>num[i];
            equ = n;
            var = m;
            for(int i = 0; i < n; i++)
            {
                for(int j = 0; j < m; j++)
                {
                    int ans = 0;
                    while(num[j]%k[i] == 0)
                    {
                        ans ++;
                        num[j]/=k[i];
                    }
                    if(ans%2) a[i][j] = 1;
                }
            }
            int N = Gauss();
            strcpy(str1, "1");
            for(int i = 0; i < N; i++)
            {
                Add(str1, str1, str2);
                strcpy(str1, str2);
            }
            Sub_1(str1);
            for(int i = strlen(str1)-1; i >= 0; i--) cout<<str1[i];
            cout<<endl;
        }
        return 0;
    }


    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    mssql 循环的写法,备用
    用了十几年的windows记录下我不知道的几个快捷键
    折腾了下java下webservice,折腾了大半天,居然是eclipse的版本不对
    连接Linux 下mysql 慢的问题,解决之
    解决windows7蓝屏的方法
    MySQL錯誤:Value '00000000' can not be represented as java.sql.Date解決方法[转]
    jdbc连接三种数据库的连接语句写法(备查)
    遇到一个json解析的错误,费了好大的劲,最后发现是少了一个包
    【转】The reference to entity "characterEncoding" must end with the ';' delimiter
    synaptics 插入USB鼠标禁用,网上
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4826530.html
Copyright © 2011-2022 走看看