建立方程组消元,结果为2 ^(自由变元的个数) - 1
采用高斯消元求矩阵的秩
#include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<map> #include<queue> #include<vector> #include<cmath> #include<utility> using namespace std; typedef long long LL; const int N = 108, INF = 0x3F3F3F3F; const double eps = 1e-8; int a[N][N]; template<typename T> int gauss_jordan(T A[N][N], int n, int m){ int i, c; for(i = 0, c = 0; i < n && c < m; i++, c++){ int r = i; for(int j = i + 1; j < n; j++){ if(A[j][c]){ r = j; break; } } if(A[r][c] == 0){ i--; continue; } if(r != i){ for(int j = 0; j <= m; j++){ swap(A[r][j], A[i][j]); } } for(int k = 0; k < n; k++){ if(k != i && A[k][c]){ for(int j = m; j >= c; j--){ A[k][j] ^= A[i][j]; } } } } return i; } const int MAXN = 508; int prime[MAXN]; bool vis[MAXN]; int getPrime(int n){//求1~n的素数 int tot=0; memset(vis,0,sizeof(vis)); for(int i=2;i<=n;i++){ if(!vis[i]){ prime[tot++]=i; } for(int j=0;j<tot&&i*prime[j]<=n;j++){ vis[i*prime[j]]=true; if(i%prime[j]==0){//让每个合数仅被其最小的质数筛去 break; } } } return tot; } int main(){ int cnt = getPrime(500); int t; cin>>t; while(t--){ memset(a, 0, sizeof(a)); int n; cin>>n; for(int j = 0; j < n; j++){ LL x; cin>>x; for(int i = 0; i < cnt && prime[i]<= x; i++){ while(x % prime[i] == 0){ a[i][j] ^= 1; x /= prime[i]; } } } LL ans = n - gauss_jordan(a, cnt, n); //cout<<ans<<" ans\n"; cout<<((1ll << ans) - 1)<<‘\n‘; } return 0; }
时间: 2024-10-17 19:39:55