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

那么答案就是(2^power)-1

wa了几次竟然是因为高精度写错了,真是醉了...

code

/*
       解异或方程组
*/
#include <iostream>
#include <vector>
using namespace std;
const int MAXN = 211;

int prim[MAXN];
vector<int> A[MAXN];

int Gauss (int n, int m) {
    int col = 1, row = 0, tem, k = 0;
    for (; col <= m && row <= n; ++col) {
        for (tem = ++row; tem <= n && A[tem][col] == 0; ++tem);
        if (tem > n) {
            row--;
            continue;
        }
        if (tem != row)      swap (A[tem], A[row]);
        for (int i = row + 1; i <= n; ++i) {
            if (A[i][col])
                for (int j = col; j <= m; ++j)
                    A[i][j] ^= A[row][j];
        }
    }
    return m - row;
}
void init() {
    bool vis[2200] = {0};
    for (int i = 2, tol = 0; i <= 1000; ++i)
        if (!vis[i]) {
            prim[++tol] = i;
            for (int j = i; j <= 1000; j += i)
                vis[j] = 1;
        }
}
int n, m;
void output (int x) {
    if (x <= 0) {
        cout << 0 << endl;
        return;
    }
    int C[1000] = {0}, len = 1;
    for (int i = 1; i <= x; ++i) {
        for (int j = 1; j <= len; ++j)
            C[j] <<= 1;
        C[1]++;
        for (int t = 1; t <= len ; t++)
            if (C[t] >= 10) {
                C[t + 1] += C[t] / 10;
                C[t] %= 10;
                if (t + 1 > len) len++;
            }
    }
    for (int i = len; i > 0; --i)
        cout << C[i];
}

int main() {
    ios::sync_with_stdio (0);
    init();
    cin >> n >> m;
    for (int i = 1; i < MAXN; i++) A[i].resize (MAXN);
    for (int i = 1, x; i <= m; ++i) {
        cin >> x;
        for (int j = 1; j <= n; ++j)
            for (; x % prim[j] == 0; x /= prim[j]) A[j][i] ^= 1;
    }
    int power = Gauss (n, m);
    output (power);
}

时间: 2024-10-11 04:05:19

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

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

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

[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 实现

bzoj 2707 [SDOI2012]走迷宫(SCC+高斯消元)

Description Morenan被困在了一个迷宫里.迷宫可以视为N个点M条边的有向图,其中Morenan处于起点S,迷宫的终点设为T.可惜的是,Morenan非常的脑小,他只会从一个点出发随机沿着一条从该点出发的有向边,到达另一个点.这样,Morenan走的步数可能很长,也可能是无限,更可能到不了终点.若到不了终点,则步数视为无穷大.但你必须想方设法求出Morenan所走步数的期望值. Input 第1行4个整数,N,M,S,T 第[2, M+1]行每行两个整数o1, o2,表示有一条从o