Kyopro Library
 
読み取り中…
検索中…
一致する文字列を見つけられません
linear_equation.hpp
[詳解]
1#include"../../kyopro_library/template.hpp"
2
3/// @brief F_2 上の連立線形方程式
4/// @ref https://mathlandscape.com/solution-sp/
5/// @ref https://yukicoder.me/submissions/1011997
6/// @ref verify: https://yukicoder.me/problems/no/2895
7/// @ref verify: https://yukicoder.me/problems/no/3229
8/// @ref verify: https://judge.yosupo.jp/problem/system_of_linear_equations_mod_2
9
10/// @brief 掃き出し法
11/// @param a 連立方程式 Ax=b の拡大係数行列
12/// @param col 拡大係数行列の列数
13/// @param where ピボットとなる変数を記録するための配列
14/// @return A のランク
15template<int MAX_COL>
16int RowReduction(vector<bitset<MAX_COL>>& a, int col, vector<int>& where) {
17 int row=a.size();
18 int rank=0;
19 for(int c=0; c<col-1; c++) {
20 int pivot=rank;
21 while(pivot<row && !a[pivot][c]) pivot++;
22 if(pivot==row) continue;
23 swap(a[pivot],a[rank]);
24 where.push_back(c);
25 for(int r=0; r<row; r++) {
26 if(r!=rank && a[r][c]) a[r]^=a[rank];
27 }
28 rank++;
29 }
30 return rank;
31}
32
33/// @brief 連立線形方程式 Ax=b を解く
34/// @param col 連立方程式の変数の数
35/// @param x0 特殊解(b=0 の場合は自明解になる)
36/// @param ker Ax=0 の解空間の基底
37/// @param ONE_KER 基底のサイズが巨大な場合、基底を1つだけ求められれば良いときはtrue
38/// @note 一般解は x0 と解空間の基底の任意の線形結合で表される
39/// @attention A のサイズによっては基底のサイズが巨大になるので注意すること
40template<int MAX_COL, bool ONE_KER=false>
41int LinearEquation(vector<bitset<MAX_COL>> a, vector<bool> b, int col, vector<bool>& x0, vector<vector<bool>>& ker) {
42 int row=a.size();
43 assert(b.size()==row);
44
45 vector<bitset<MAX_COL>> a2(row);
46 for(int i=0; i<row; i++) {
47 a2[i].reset();
48 for(int j=0; j<col; j++) a2[i][j]=a[i][j];
49 if(b[i]) a2[i][col]=true;
50 }
51
52 vector<int> where;
53 int rank=RowReduction<MAX_COL>(a2,col+1,where);
54
55 for(int r=rank; r<row; r++) if(a2[r][col]) return false;
56
57 x0=vector<bool>(col,false);
58 for(int i=0; i<rank; i++) x0[where[i]]=a2[i][col];
59
60 int r=0;
61 for(int c=0; c<col; c++) {
62 if(r<rank && c==where[r]) {
63 r++;
64 continue;
65 }
66 vector<bool> x(col);
67 x[c]=true;
68 for(int r2=0; r2<r; r2++) x[where[r2]]=a2[r2][c];
69 ker.push_back(x);
70
71 if (ONE_KER) return true;
72 }
73
74 return true;
75}
int RowReduction(vector< bitset< MAX_COL > > &a, int col, vector< int > &where)
F_2 上の連立線形方程式 https://mathlandscape.com/solution-sp/ https://yukicoder.me/submissions/1011997 verify:...
int LinearEquation(vector< bitset< MAX_COL > > a, vector< bool > b, int col, vector< bool > &x0, vector< vector< bool > > &ker)
連立線形方程式 Ax=b を解く