• xor方程组消元 UVA 11542 Square


    题目传送门

    题意:给n个数,选择一些数字乘积为平方数的选择方案数。训练指南题目。

    分析:每一个数字分解质因数。比如4, 6, 10, 15,, 令表示选择第i个数字,那么,如果p是平方数,那么每个质因数上的指数为偶数,x1系数为2已经是偶数不考虑。可以转换为异或为0判断偶数,即奇数置为1,偶数置为0,然后n个数字m个质因数的增广矩阵消元看有几个自由变量(取0或1无所谓),答案是2^r - 1(全部都不取方案不算)

    #include <bits/stdc++.h>
    
    const int N = 500 + 5;
    bool vis[N];
    int prime[N];
    int A[N][105];
    
    void sieve(int n) {
        int m = sqrt (n + 0.5);
        for (int i=2; i<=m; ++i) {
            if (!vis[i]) {
                for (int j=i*2; j<=n; j+=i) {
                    vis[j] = true;
                }
            }
        }
    }
    
    int gen_prime(int n) {
        memset (vis, false, sizeof (vis));
        sieve (n);
        int c = 0;
        for (int i=2; i<=n; ++i) {
            if (!vis[i]) {
                prime[c++] = i;
            }
        }
        return c;
    }
    
    int rank(int m, int n) {
        int i = 0, j = 0;
        while (i < m && j < n) {
            int r = i;
            for (int k=i; k<m; ++k) {
                if (A[k][j]) {
                    r = k;
                    break;
                }
            }
            if (A[r][j]) {
                if (r != i) {
                    //!
                    for (int k=0; k<=n; ++k) {
                        std::swap (A[r][k], A[i][k]);
                    }
                }
                for (int k=i+1; k<m; ++k) {
                    if (A[k][j]) {
                        for (int c=i; c<=n; ++c) {
                            A[k][c] ^= A[i][c];
                        }
                    }
                }
                ++i;
            }
            ++j;
        }
        return i;
    }
    
    //Running_Time
    int main() {
        int T; scanf ("%d", &T);
        int m = gen_prime (500);
        while (T--) {
            int n; scanf ("%d", &n);
            memset (A, 0, sizeof (A));
            int maxp = 100;
            for (int i=0; i<n; ++i) {
                long long x; scanf ("%lld", &x);
                for (int j=0; j<m; ++j) {
                    while (x % prime[j] == 0) {
                        x /= prime[j];
                        A[j][i] ^= 1;
                        maxp = std::max (maxp, j);
                    }
                }
            }
            int r = rank (maxp+1, n);
            std::cout << ((1LL << (n - r)) - 1) << '
    ';
        }
    
        return 0;
    }
    

      

  • 相关阅读:
    gcc和g++的区别
    configure svn server on win
    FD_SET,FD_ISSET,FD_ZERO,select
    intel中的cr寄存器
    Linux系统环境下的Socket编程详细解析
    可重入函数与不可重入函数
    初步认识迭代服务器和并发服务器
    排序
    fd_set 用法
    MFC消息映射
  • 原文地址:https://www.cnblogs.com/Running-Time/p/5365681.html
Copyright © 2020-2023  润新知