intgauss(vector<vector<db>>& a, int n){ int r = 1; // 当前行 for (int c = 1; c <= n; c++) { // 消元进行到第c列 // 1.找到c列的最大行t int t = r; for (int i = r; i <= n; i++) if (fabs(a[i][c]) > fabs(a[t][c])) t = i; if (fabs(a[t][c]) < eps) continue; // c列已全为0
// 2.把最大行换到上面 for (int i = c; i <= n + 1; i++) swap(a[t][i], a[r][i]);
// 3.把当前行r的第一个数,变成1 for (int i = n + 1; i >= c; i--) a[r][i] /= a[r][c];
// 4.把当前列c下面的所有数,全部消成0 for (int i = r + 1; i <= n; i++) if (fabs(a[i][c]) > eps) for (int j = n + 1; j >= c; j--) a[i][j] -= a[i][c] * a[r][j]; r++; // 从下一行开始消元下一列 } if (r <= n) { // 说明已经提前变成梯形矩阵 for (int i = r; i <= n; i++) { if (fabs(a[i][n + 1]) > eps) return0; } // 左边=0,右边≠0,无解 return2; // 0==0,无穷多解 } // 5.唯一解,从下往上回代,得到方程的解 for (int i = n; i >= 1; i--) for (int j = i + 1; j <= n; j++) a[i][n + 1] -= a[i][j] * a[j][n + 1]; return1; }
voidsolve(){ int n; cin >> n; vector b(n + 1, vector<db>(n + 2)); for (int i = 1; i <= n; i++) for (int j = 1; j <= n + 1; j++) cin >> b[i][j]; int t = gauss(b, n); if (t == 0) { cout << "No solution " << endl; } elseif (t == 2) { cout << "Infinite group solutions" << endl; } else { for (int i = 1; i <= n; i++) { baoliu(b[i][n + 1], 2); cout << endl; } } }
gauss(vector<vector<int>>& a, int n, vector<int>& solution) { vector<int> freevar; // 记录自由变量对应的列 vector<int> pivot(n + 1, -1); // 记录每一行的主元所在的列 //solution.assign(n + 1, 0); int r = 1; for (int c = 1; c <= n; c++) { int t = r; // 找到当前列中的主元 for (int i = r; i <= n; i++) { if (a[i][c]) { t = i; break; } } if (!a[t][c]) { freevar.push_back(c); continue; // 当前列没有主元,继续到下一列 } pivot[r] = c; // 第 r 行的主元在 c 列 if (t != r) { // 交换行,将主元行放在第 r 行 for (int i = c; i <= n + 1; i++) swap(a[r][i], a[t][i]); } // 消去主元下方的所有行 for (int i = r + 1; i <= n; i++) { if (a[i][c]) for (int j = n + 1; j >= c; j--) a[i][j] ^= a[r][j]; } r++; }
// 检查是否有解 for (int i = r; i <= n; i++) { if (a[i][n + 1]) return0; // 无解 } //int tot = 0; int rksz = r - 1; // 这是系数矩阵的秩 // 自由变量根据题目要求情况去赋值 for (auto i : freevar) solution[i] =0; //------------------------------ for (int i = rksz; i >= 1; i--) { int sum = a[i][n + 1]; for (int j = 1; j <= n; j++) { if (j == pivot[i]) { continue; } // 如果不是主元所在的列 sum ^= (a[i][j] * solution[j]); // 右边已经求出来的,左边自由变量遗留 } solution[pivot[i]] = sum; // 求解对应的主元变量 } assert(rksz <= n); if (rksz < n) return2; // 无穷多解 return1; // 唯一解 } // int t = gauss(b, n, sol);
db b[N][N]; // 增广矩阵 int id[N]; // id[j]=i:表示第j列的答案最终在第i行被计算 int rid[N]; // 第i行可以算出第j列的主元 voidprint(int n, int m){ for (int i = 1; i <= n; i++) { for (int j = 1; j <= m + 1; j++) { cerr << setiosflags(ios::left) << setw(5) << b[i][j]; } cerr << endl; } cerr << "---------------------" << endl; } int rksz; int freenum; vector<db> ans; intgauss(db a[][N], int n, int m){ // n个方程,m个未知数。默认多余自由变量为0,记录映射关系 int r = 1; // 当前行 for (int c = 1; c <= m; c++) { // 消元进行到第c列 // 1.找到c列的最大行t int t = r; for (int i = r; i <= n; i++) if (fabs(a[i][c]) > fabs(a[t][c])) t = i; if (t > n || fabs(a[t][c]) < eps) continue; // c列已全为0 assert(t <= n); // 2.把最大行换到上面 for (int i = c; i <= m + 1; i++) swap(a[t][i], a[r][i]); // 3.把当前行r的第一个数,变成1 for (int i = m + 1; i >= c; i--) a[r][i] /= a[r][c]; // 4.把当前列c下面的所有数,全部消成0 for (int i = r + 1; i <= n; i++) if (fabs(a[i][c]) > eps) for (int j = m + 1; j >= c; j--) a[i][j] -= a[i][c] * a[r][j]; id[c] = r; rid[r] = c; r++; // 从下一行开始消元下一列 } //--------------------------- // print(n, m); rksz = r - 1; freenum = m - r + 1; ans.resize(m + 1); //------------------------ if (r <= m) { // 说明已经提前变成梯形矩阵 for (int i = r; i <= n; i++) { if (fabs(a[i][m + 1]) > eps) return0; // 左边=0,右边≠0,无解 } } for (int i = 1; i <= m; i++) { if (id[i] == 0) { // deb(i); ans[i] = 1; // 如果第i列的主元没有对应行,自由变量随机赋值 } } // 5.唯一解,从下往上回代,得到方程的解 for (int i = rksz; i >= 1; i--) { for (int j = 1; j <= m; j++) { // 左侧自由变量残余,右侧已经算出来的以及右侧自由变量 if (j == rid[i]) continue; a[i][m + 1] -= a[i][j] * ans[j]; } // deb(rid[i]); ans[rid[i]] = a[i][m + 1]; // 第i行的主元在rid[i]列 } if (m > n) { return2; } else { // m<=n; assert(rksz <= m); if (rksz == m) return1; return2; } } voidsolve(){ int n, m; cin >> n >> m; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cin >> b[i][j]; } } for (int i = 1; i <= n; i++) cin >> b[i][m + 1]; int t = gauss(b, n, m); // n个方程,m个未知数 deb(t, rksz, freenum); if (t == 0) { cout << "NO" << endl; } else { cout << "YES" << endl; for (int i = 1; i <= m; i++) cout << fixed << setprecision(12) << ans[i] << endl; } }
int rksz; // 还没有处理n方程,m变量的情况(n>m) intgauss(vector<vector<int>>& a, int n, int m, vector<int>& solution){ vector<int> freevar; // 记录自由变量对应的列 vector<int> pivot(n + 1, -1); // 记录每一行的主元所在的列 int r = 1; for (int c = 1; c <= m; c++) { int t = r; // 找到当前列中的主元 for (int i = r; i <= n; i++) { if (a[i][c]) { t = i; break; } } // if (t > n) // deb(t, n, c, m); // assert(t <= n); // assert(c <= m); if (t > n || !a[t][c]) { freevar.push_back(c); continue; // 当前列没有主元,继续到下一列 } pivot[r] = c; // 第 r 行的主元在 c 列 if (t != r) { // 交换行,将主元行放在第 r 行 for (int i = c; i <= m + 1; i++) swap(a[r][i], a[t][i]); } // 消去主元下方的所有行 for (int i = r + 1; i <= n; i++) { if (a[i][c]) for (int j = m + 1; j >= c; j--) a[i][j] ^= a[r][j]; } r++; }
// 检查是否有解 for (int i = r; i <= n; i++) { if (a[i][m + 1]) return0; // 无解 } // int tot = 0; rksz = r - 1; // 这是系数矩阵的秩 // 自由变量根据题目要求情况去赋值 for (auto i : freevar) solution[i] = 0; //------------------------------ for (int i = rksz; i >= 1; i--) { int sum = a[i][m + 1]; for (int j = 1; j <= m; j++) { if (j == pivot[i]) { continue; } // 如果不是主元所在的列 sum ^= (a[i][j] * solution[j]); // 右边已经求出来的,左边自由变量遗留 } solution[pivot[i]] = sum; // 求解对应的主元变量 } // assert(rksz <= m); if (rksz < m) return2; // 无穷多解 return1; // 唯一解 } // int t = gauss(b, n,m, sol);
int rksz; // 还需要处理m方程,n变量,m>n #define bit(x) bitset<(x)> int gauss(vector<bit(5002)>& a, int n, int m, vector<int>& solution) { vector<int> freevar; // 记录自由变量对应的列 vector<int> pivot(n + 1, -1); // 记录每一行的主元所在的列 int r = 1; for (int c = 1; c <= m; c++) { int t = r; // 找到当前列中的主元 for (int i = r; i <= n; i++) { if (a[i][c]) { t = i; break; } } if (t > n || !a[t][c]) { freevar.push_back(c); continue; // 当前列没有主元,继续到下一列 } pivot[r] = c; // 第 r 行的主元在 c 列 if (t != r) { // 交换行,将主元行放在第 r 行 swap(a[r], a[t]); } // 消去主元下方的所有行 for (int i = r + 1; i <= n; i++) { if (a[i][c]) a[i] ^= a[r]; } r++; }
// 检查是否有解 for (int i = r; i <= n; i++) { if (a[i][m + 1]) return 0; // 无解 } // int tot = 0; rksz = r - 1; // 这是系数矩阵的秩 // 自由变量根据题目要求情况去赋值 for (auto i : freevar) solution[i] = 0; //------------------------------ for (int i = rksz; i >= 1; i--) { int sum = a[i][m + 1]; for (int j = 1; j <= m; j++) { if (j == pivot[i]) { continue; } // 如果不是主元所在的列 sum ^= (a[i][j] * solution[j]); // 右边已经求出来的,左边自由变量遗留 } solution[pivot[i]] = sum; // 求解对应的主元变量 } // assert(rksz <= m); if (rksz < m) return 2; // 无穷多解 return 1; // 唯一解 } // int t = gauss(b, n,m, sol);
int rksz; intgauss(vector<vector<int>>& a, int n, int m){ vector<int> freevar; // 记录自由变量对应的列 vector<int> pivot(n + 1, -1); // 记录每一行的主元所在的列 int r = 1; for (int c = 1; c <= m; c++) { int t = r; // 找到当前列中的主元 for (int i = r; i <= n; i++) { if (a[i][c]) { t = i; break; } } if (!a[t][c]) { freevar.push_back(c); continue; // 当前列没有主元,继续到下一列 } pivot[r] = c; // 第 r 行的主元在 c 列 if (t != r) { // 交换行,将主元行放在第 r 行 for (int i = c; i <= m + 1; i++) swap(a[r][i], a[t][i]); } // 消去主元下方的所有行 for (int i = r + 1; i <= n; i++) { if (a[i][c]) for (int j = m + 1; j >= c; j--) a[i][j] ^= a[r][j]; } r++; } // 检查是否有解 for (int i = r; i <= n; i++) { if (a[i][m + 1]) return0; // 无解 } rksz = r - 1; // 这是系数矩阵的秩 assert(rksz <= m); if (rksz < m) return2; // 无穷多解 return1; // 唯一解 } vector<int> primes, minp; int cnt; voidsieve(int n){ minp.assign(n + 1, 0); primes.clear();
for (int i = 2; i <= n; i++) { if (minp[i] == 0) { minp[i] = i; primes.push_back(i); }
for (auto p : primes) { if (i * p > n) { break; } minp[i * p] = p; if (p == minp[i]) { break; } } } cnt = primes.size(); deb(cnt); } int tt = 0; voidsolve(){ int n; tt++; cin >> n; vector<int> a(n + 1); for (int i = 1; i <= n; i++) cin >> a[i]; vector<vector<int>> b(cnt + 1, vector<int>(n + 2)); for (int i = 1; i <= n; i++) { int x = a[i]; for (int j = 1; j <= cnt; j++) { int v = 0; while (x % primes[j - 1] == 0) { x /= primes[j - 1]; v++; } b[j][i] = v % 2; } } int t = gauss(b, cnt, n); deb(rksz); if (t == 0) cout << 0 << endl; else { assert(rksz <= n); int ans = 1LL; for (int i = 1; i <= n - rksz; i++) ans = (ans * 2) % mod; ans = (ans + mod - 1) % mod; cout << "Case #" << tt << ":" << endl; cout << ans << endl; } }