高斯消元
Posted __AiR_H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高斯消元相关的知识,希望对你有一定的参考价值。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <queue> 7 #include <vector> 8 #include <stack> 9 #include <map> 10 #include <set> 11 #include <cmath> 12 #include <cctype> 13 #include <ctime> 14 #include <bitset> 15 16 using namespace std; 17 18 #define REP(i, n) for (int i = 0; i < (n); ++i) 19 #define eps 1e-9 20 21 typedef long long ll; 22 typedef pair<int, int> pii; 23 24 const int INF = 0x7fffffff; 25 const int maxn = 55; 26 struct Matrix { int det[maxn][maxn]; }; 27 int T, n, m, q, Case = 0; 28 Matrix A, A_t; 29 30 int solve(Matrix A, int m, int n) { 31 int i = 0, j = 0, k, r, u; 32 while (i < m && j < n) { 33 r = i; 34 for (k = i; k < m; ++k) { 35 if (A.det[k][j]) { r = k; break; } 36 } 37 if (!A.det[r][j]) { ++j; continue; } 38 if (r != i) { 39 for (int k = 0; k <= n; ++k) { swap(A.det[r][k], A.det[i][k]); } 40 } 41 for (u = i + 1; u < m; ++u) if (A.det[u][j]) { 42 for (k = i; k <= n; ++k) { A.det[u][k] ^= A.det[i][k]; } 43 } 44 ++i; ++j; 45 } 46 for (u = i; u < m; ++u) { 47 if (A.det[u][n]) { return -1; } 48 } 49 return i; 50 } 51 52 int main() { 53 #ifdef __AiR_H 54 freopen("in.txt", "r", stdin); 55 // freopen("out.txt", "w", stdout); 56 #endif // __AiR_H 57 scanf("%d", &T); 58 while (T--) { 59 scanf("%d %d", &n, &m); int k, x; 60 memset(A_t.det, 0, sizeof(A_t.det)); 61 for (int i = 0; i < m; ++i) { 62 scanf("%d", &k); 63 for (int j = 0; j < k; ++j) { 64 scanf("%d", &x); A_t.det[x - 1][i] = 1; 65 } 66 } 67 scanf("%d", &q); printf("Case %d:\n", ++Case); 68 while (q--) { 69 A = A_t; 70 for (int i = 0; i < n; ++i) { scanf("%d", &A.det[i][m]); } 71 int ans = solve(A, n, m); if (ans == -1) { printf("0\n"); continue; } 72 ans = m - ans; printf("%lld\n", 1ll << ans); 73 } 74 } 75 return 0; 76 }
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <queue> 7 #include <vector> 8 #include <stack> 9 #include <map> 10 #include <set> 11 #include <cmath> 12 #include <cctype> 13 #include <ctime> 14 #include <bitset> 15 16 using namespace std; 17 18 #define REP(i, n) for (int i = 0; i < (n); ++i) 19 #define eps 1e-9 20 21 typedef long long ll; 22 typedef pair<int, int> pii; 23 24 const int INF = 0x7fffffff; 25 const int maxn = 2000 + 10; 26 const ll mod = 1e9 + 7; 27 int prime[maxn]; 28 int prime_cnt = 0, T, n, Case = 0; 29 bool is_prime[maxn]; 30 31 struct Matrix { int det[maxn][maxn]; }; 32 Matrix A; 33 34 void init() { 35 memset(is_prime, true, sizeof(is_prime)); 36 is_prime[0] = is_prime[1] = false; 37 for (int i = 2; i < maxn; ++i) { 38 if (is_prime[i]) { prime[prime_cnt++] = i; } 39 for (int j = 0; j < prime_cnt; ++j) { 40 if (i * prime[j] >= maxn) { break; } 41 is_prime[i * prime[j]] = false; 42 if (i % prime[j] == 0) { break; } 43 } 44 } 45 } 46 int solve(int m, int n) { 47 int i = 0, j = 0, k, r, u; 48 while (i < m && j < n) { //当前正在处理第i个方程,第j个变量 49 r = i; 50 for (k = i; k < m; ++k) { 51 if (A.det[k][j]) { r = k; break; } 52 } 53 if (!A.det[r][j]) { ++j; continue; } 54 if (r != i) { 55 for (k = 0; k <= n; ++k) { swap(A.det[r][k], A.det[i][k]); } 56 } 57 for (u = i + 1; u < m; ++u) if (A.det[u][j]) { 58 for (k = i; k <= n; ++k) { A.det[u][k] ^= A.det[i][k]; } 59 } 60 ++i; ++j; 61 } 62 return i; 63 } 64 ll my_pow(ll x, ll y) { 65 ll ret = 1, t = x; 66 while (y) { 67 if (y & 1) { ret *= t; ret %= mod; } 68 y >>= 1; t *= t; t %= mod; 69 } 70 return ret; 71 } 72 73 int main() { 74 #ifdef __AiR_H 75 freopen("in.txt", "r", stdin); 76 // freopen("out.txt", "w", stdout); 77 #endif // __AiR_H 78 scanf("%d", &T); init(); 79 while (T--) { 80 scanf("%d", &n); memset(A.det, 0, sizeof(A.det)); 81 int maxp = 0; ll x; 82 for (int i = 0; i < n; ++i) { 83 scanf("%lld", &x); 84 for (int j = 0; j < prime_cnt; ++j) { 85 while (x % prime[j] == 0) { 86 maxp = max(maxp, j); x /= prime[j]; A.det[j][i] ^= 1; 87 } 88 } 89 } 90 printf("Case #%d:\n", ++Case); 91 int ans = solve(maxp + 1, n); ans = n - ans; 92 ll ret = my_pow(2, ans); --ret; 93 if (ret < 0) { ret += mod; } printf("%lld\n", ret); 94 } 95 return 0; 96 }
以上是关于高斯消元的主要内容,如果未能解决你的问题,请参考以下文章