UVA 11542 - Square(异或方程组消元经典题目)

题目链接

11542 - Square

分析

每一个元素有选或则不选两种状态,因此设第 ivi,xi 表示每个元素要不要选共 n 个变元,由于我们可以先求出 500 以内的素数,将选出来的数进行素因子分解后有 pk1xj1+k2xj2+,kixji1 指数部分应该mod 2 为0的这样就会有m(500以内的素数个数)个方程,而变元为 n ,只需要求解系数矩阵的rank由线性方程组的性质,不受约束的变量就有 nrank 个最终对于此内变量的任意一种组合都是答案共 2nrank1()

AC code

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define pb push_back
#define mp make_pair
#define PI acos(-1)
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define INF64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int MOD = 1e9+7;
const int MAX_P = 2e4+10;
const int maxn = 500+10;
const int MAX_V = 5e5+10;
const double eps = 1e-8;
typedef long long LL;
typedef long double DB;
typedef pair<int,int> Pair;
typedef int Matrix[maxn][maxn];

int prime[maxn];
int get_prime(int maxv){
    memset(prime,0,sizeof(prime));
    int cnt =0;
    for(int i=2 ; i<=maxv ; ++i){
        if(!prime[i]){
            prime[cnt++] = i;
        }
        for(int j =0 ; j1;
            if(i % prime[j] == 0)break;
        }
    }
    return cnt;
}

int my_rank(Matrix &A, int m,int n){
    int i=0 ,j = 0,r;
    while (iint r =i ;
        for(int k =i ; kif(A[k][j]){r=k ; break;}
        if(A[r][j]){
            if(r != i)for(int k = 0 ; kfor(int u= i+1 ; uif(A[u][j])
                    for(int k = j ; kreturn i;
}

Matrix A;
int main() {

    int m = get_prime(500);
    int T;
    cin>>T;
    while (T--) {
        int n;
        scanf("%d",&n );
        memset(A,0,sizeof(A));
        int maxp = 0;
        for(int i=0 ;iscanf("%lld",&x );
            for(int j=0 ; jif(x %prime[j] == 0){
                    while (x%prime[j] ==0) {
                        x /= prime[j];
                        maxp = max(maxp,j);
                        A[j][i] ^=1;
                    }
                }
            }
        }
        int r = my_rank(A,maxp+1,n);
        printf("%lld\n",(1LL << (n-r)) -1 );

    }

    return 0;
}

你可能感兴趣的:(算法刷题)