高斯-約旦消元法
阿新 • • 發佈:2020-07-15
一般的高斯消元需要回代,所以就顯得比較贅餘,一般選用高斯-約旦消元法
首先給定一個多元一次方程組
我們可以直接寫A出它的增廣矩陣直接求出他的解
同理對於方矩陣A
我們可以利用初等變化求出它的逆矩陣
證明如下:
對於矩陣(A,B)進行初等變化變為(E,P)易知p就是A的逆矩陣
關於高斯-約旦消元法就是利用此種方法求解
接下來進行初等變化
分為步
1.找出第I列的主元(元素值最大的那個)然後交換到第I行(已經交換到前面的就無需考慮)
2.求出對角線也就是第(i,i)個元素的逆元(由於需要mod,所以該逆元可以理解為他的倒數
3.直接更改當前行乘以逆元,你會發現第(i,i)個元素直接就是1
4.所以隨後只要減去1*該列除了主元以外其他元素的值,依次消元
如下圖所示1.
2.
3.
4.
程式碼如下
#include <bits/stdc++.h> using namespace std; #define ll long long #define re register const int maxn=300; const int mod=998244353; ll a[maxn][maxn<<1]; ll quickpow(ll a,ll b,ll p) { ll ans=1; while (b) { if (b&1)///b為奇數 ans=(ans*a)%p; a=(a*a)%p;///b為偶數 b>>=1; } return ans; } for(re int i=1,t;i<=n;++i) { t=i; for(re int j=i+1;j<=n;++j)///找出每一列的最大主元 { if(abs(a[j][i])>abs(a[t][i]))///找尋最大主元 { t=j; } } if(i^t)///相當於i!=t,保證不在當前行 { swap(a[i],a[t]);///交換行 } ll w=quickpow(a[i][i],mod-2,mod);///直接求出對角元素值,方便消元 for(re int j=1;j<=n;++j) { if(j!=i)///當前行直接乘以逆元即可,無需進行消元 { ll tmp=a[j][i]*w%mod;///主元乘以逆元 for(int k=i;k<=(n<<1);++k) { a[j][k]=((a[j][k]-a[i][k]*tmp)%mod+mod)%mod;///該點元素直接減去i行元素乘以對稱點(i i)的逆元 } } } for(re int j=1;j<=(n<<1);++j)a[i][j]=(w*a[i][j])%mod;///最後當前行直接乘以逆元保證主元為1,最後能得到單位矩陣 }