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


3

[submit]

#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;
}

SGU 200. Cracking RSA(高斯消元+高精度),布布扣,bubuko.com

时间: 2024-10-27 03:38:00

SGU 200. Cracking RSA(高斯消元+高精度)的相关文章

SGU 200.Cracking RSA(高斯消元)

时间限制:0.25s 空间限制:4M 题意: 给出了m(<100)个数,这m个数的质因子都是前t(<100)个质数构成的. 问有多少个这m个数的子集,使得他们的乘积是完全平方数. Solution: 要使乘积为完全平方数,那么对于乘积的每个质因子的个数要为偶数. 可以先打出前100个质数,来看第i个质数Pi,对于第j个数Kj,如果它含有奇数个质数Pi,那么矩阵A[i][j]的值为1,显然增广矩阵的值应该全为0. 这样就构造出了一个n*m的xor方程组. 利用高斯消元求出变元的个数power 那

Acdream1217 Cracking&#39; RSA(高斯消元)

题意:给你m个数(m<=100),每个数的素因子仅来自于前t(t<=100)个素数,问这m个数的非空子集里,满足子集里的数的积为完全平方数的有多少个. 一开始就想进去里典型的dp世界观里,dp[n][mask]表示前n个数里为mask的有多少个,但显然这里t太大了.然后又YY了很多很多.像m少的时候应该用的是高消.即对每个因子列一个xor方程,然后高斯消元,其中自由元的个数就是可以随便取的,所以答案是2^(自由元个数),然后把空集的减掉,就是2^(自由元)-1,不过大数是必须的. #inclu

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> #includ

sgu200--Cracking RSA(高斯消元问题5,求乘积为完全平方数的种数)

Cracking RSA Time Limit:250MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Description <script type="text/javascript" language="javascript" src="http://acm.sgu.ru/js/jquery.js"><script

SGU 275 To xor or not to xor (高斯消元)

题目地址:SGU 275 首先,贪心的思想,每一二进制位上要尽量是1,而能不能是1用高斯消元来解决.当该位有一个可以使之为1的变元时,就说明这位可以为1,而且令该变元控制该位,然后向低位消元. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h>

SGU 275 To xor or not to xor 高斯消元求N个数中选择任意数XORmax

275. To xor or not to xor The sequence of non-negative integers A1, A2, ..., AN is given. You are to find some subsequence Ai 1, Ai 2, ..., Ai k (1 <= i 1 < i 2 < ... < i k<= N) such, that Ai 1 XOR Ai 2 XOR ... XOR Ai k has a maximum value.

[ACM] POJ 2947 Widget Factory (高斯消元)

Widget Factory Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 4436   Accepted: 1502 Description The widget factory produces several different kinds of widgets. Each widget is carefully built by a skilled widgeteer. The time required to

UVA 1397 - The Teacher&#39;s Side of Math(高斯消元)

UVA 1397 - The Teacher's Side of Math 题目链接 题意:给定一个x=a1/m+b1/n,求原方程组 思路:由于m*n最多20,所有最高项只有20,然后可以把每个此项拆分,之后得到n种不同无理数,每一项为0,就可以设系数为变元,构造方程进行高斯消元 一开始用longlong爆了,换成分数写法也爆了,又不想改高精度,最后是机智的用了double型过的,不过用double精度问题,所以高斯消元的姿势要正确,并且最后输出要注意-0的情况 代码: #include <c

[BZOJ 2854] civilization 高斯消元

题意 给定 $n$, $A_{n\times n}, B = \left\{ b_i \right\}$ . 解方程 $Ax = B^T$ . $n \le 200, A_{ij} \in [- {10} ^ 9, {10} ^ 9]$ . 保证 $x_i \in [- {10} ^ {18}, {10} ^ {18}]$ . 分析 大素数取模下高斯消元, 通过 CRT 进行合并. http://blog.csdn.net/owen_hzt/article/details/41493637 实现