Biến đổi ma trận augmented \([A | b]\) thành dạng bậc thang (row echelon form) bằng các phép biến đổi hàng:
- Hoán đổi 2 hàng
- Nhân hàng với hằng số khác 0
- Cộng bội của hàng này vào hàng khác
// Giải hệ phương trình tuyến tính modulo MOD// Trả về nghiệm hoặc rỗng nếu vô nghiệm/vô số nghiệmvector<longlong>gaussianElimination(vector<vector<longlong>>a,vector<longlong>b){intn=a.size();intm=a[0].size();constlonglongMOD=1e9+7;// Tạo ma trận augmentedvector<vector<longlong>>aug(n,vector<longlong>(m+1));for(inti=0;i<n;i++){for(intj=0;j<m;j++)aug[i][j]=a[i][j];aug[i][m]=b[i];}vector<int>where(m,-1);for(intcol=0,row=0;col<m&&row<n;col++){// Tìm pivotintsel=row;for(inti=row;i<n;i++){if(abs(aug[i][col])>abs(aug[sel][col]))sel=i;}if(abs(aug[sel][col])<1e-9)continue;// Hoán đổi hàngswap(aug[sel],aug[row]);where[col]=row;// Khử cộtlonglonginv=powerMod(aug[row][col],MOD-2,MOD);for(inti=0;i<n;i++){if(i!=row){longlongfactor=aug[i][col]*inv%MOD;for(intj=col;j<=m;j++){aug[i][j]=(aug[i][j]-factor*aug[row][j]%MOD+MOD)%MOD;}}}row++;}// Lấy nghiệmvector<longlong>x(m,0);for(inti=0;i<m;i++){if(where[i]!=-1){x[i]=aug[where[i]][m]*powerMod(aug[where[i]][i],MOD-2,MOD)%MOD;}}// Kiểm tra vô nghiệmfor(inti=0;i<n;i++){longlongsum=0;for(intj=0;j<m;j++)sum=(sum+x[j]*aug[i][j])%MOD;if((sum-aug[i][m]+MOD)%MOD!=0)return{};// Vô nghiệm}returnx;}
MOD=10**9+7defgaussian_elimination(a,b):n=len(a)m=len(a[0])aug=[a[i][:]+[b[i]]foriinrange(n)]where=[-1]*mcol,row=0,0whilecol<mandrow<n:sel=rowforiinrange(row,n):ifabs(aug[i][col])>abs(aug[sel][col]):sel=iifabs(aug[sel][col])<1e-9:col+=1continueaug[sel],aug[row]=aug[row],aug[sel]where[col]=rowinv=pow(aug[row][col],MOD-2,MOD)foriinrange(n):ifi!=row:factor=aug[i][col]*inv%MODforjinrange(col,m+1):aug[i][j]=(aug[i][j]-factor*aug[row][j]%MOD+MOD)%MODrow+=1col+=1x=[0]*mforiinrange(m):ifwhere[i]!=-1:x[i]=aug[where[i]][m]*pow(aug[where[i]][i],MOD-2,MOD)%MOD# Kiểm tra vô nghiệmforiinrange(n):s=sum(x[j]*aug[i][j]forjinrange(m))%MODif(s-aug[i][m]+MOD)%MOD!=0:returnNonereturnx
longlongdeterminant(vector<vector<longlong>>a){intn=a.size();constlonglongMOD=1e9+7;longlongdet=1;for(intcol=0;col<n;col++){intsel=col;for(introw=col;row<n;row++){if(abs(a[row][col])>abs(a[sel][col]))sel=row;}if(abs(a[sel][col])<1e-9)return0;if(sel!=col){swap(a[sel],a[col]);det=(MOD-det)%MOD;// nhân -1}det=det*a[col][col]%MOD;longlonginv=powerMod(a[col][col],MOD-2,MOD);for(introw=col+1;row<n;row++){longlongfactor=a[row][col]*inv%MOD;for(intj=col;j<n;j++){a[row][j]=(a[row][j]-factor*a[col][j]%MOD+MOD)%MOD;}}}returndet;}
// Trả về ma trận nghịch đảo hoặc ma trận rỗng nếu không khả nghịchvector<vector<longlong>>inverseMatrix(vector<vector<longlong>>a){intn=a.size();constlonglongMOD=1e9+7;// Tạo augmented [A | I]vector<vector<longlong>>aug(n,vector<longlong>(2*n,0));for(inti=0;i<n;i++){for(intj=0;j<n;j++)aug[i][j]=a[i][j];aug[i][n+i]=1;}// Khử Gaussfor(intcol=0;col<n;col++){intsel=col;for(introw=col;row<n;row++){if(abs(aug[row][col])>abs(aug[sel][col]))sel=row;}if(abs(aug[sel][col])<1e-9)return{};// Không khả nghịchswap(aug[sel],aug[col]);longlonginv=powerMod(aug[col][col],MOD-2,MOD);for(intj=0;j<2*n;j++)aug[col][j]=aug[col][j]*inv%MOD;for(introw=0;row<n;row++){if(row!=col){longlongfactor=aug[row][col];for(intj=0;j<2*n;j++){aug[row][j]=(aug[row][j]-factor*aug[col][j]%MOD+MOD)%MOD;}}}}// Lấy phần nghịch đảovector<vector<longlong>>inv(n,vector<longlong>(n));for(inti=0;i<n;i++)for(intj=0;j<n;j++)inv[i][j]=aug[i][n+j];returninv;}