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);
}
View Code

 

posted @ 2014-10-24 23:00  keambar  阅读(216)  评论(0编辑  收藏  举报