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

 

你可能感兴趣的:(rack)