OI模板 高斯消元
高斯消元
//P3389
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
const double eps = 1e-4;
double a[N][N];
int n;
int gauss(){
int c, r;
for(c = 1, r = 1; c <= n; ++ c){
int tmp = r;
for(int i = r; i <= n; ++ i){
if(fabs(a[i][c]) > fabs(a[tmp][c])){
tmp = i;
}
}
if(fabs(a[tmp][c]) < eps){
continue;
}
swap(a[tmp], a[r]);
double val = a[r][c];
for(int i = 1; i <= n+1; ++ i){
a[r][i] /= val;
}
for(int i = 1; i <= n; ++ i){
if(i == r) continue;
val = a[i][c];
for(int j = 1; j <= n+1; ++ j){
a[i][j] -= a[r][j] * val;
}
}
++ r;
}
if(r <= n){
for(int i = r; i <= n; ++ i){
if(fabs(a[i][n+1]) > eps){
return 2;// no solution
}
}
return 1;//inf
}
return 0;
}
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; ++ i){
for(int j = 1; j <= n + 1; ++ j){
scanf("%lf", &a[i][j]);
}
}
if(gauss()){
puts("No Solution");
return 0;
}
for(int i = 1; i <= n; ++ i){
printf("%.2lf\n", a[i][n+1]);
}
return 0;
}
矩阵求逆
设求 A A A 矩阵的逆,则在高斯消元把 A A A 矩阵通过初等行变换转换为单位矩阵时,对另一个单位矩阵 B B B 进行相同的操作,最后的 B B B 即为 A A A 的逆矩阵。
//P4783
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 410;
const ll P = 1e9 + 7;
int n;
ll a[N][N], b[N][N];
ll qp(ll a, ll b){
ll ans = 1;
while(b){
if(b & 1){
ans = ans * a % P;
}
a = a * a % P;
b >>= 1;
}
return ans;
}
ll inv(ll x){
return qp(x, P-2);
}
int gauss(){
int c, r;
ll val;
for(c = 1, r = 1; c <= n; ++ c){
int tmp = r;
for(int i = r; i <= n; ++ i){
if(a[i][c]){
tmp = i;
}
}
if(!a[tmp][c]){
continue;
}
swap(a[tmp], a[r]);
swap(b[tmp], b[r]);
val = inv(a[r][c]);
for(int i = 1; i <= n; ++ i){
a[r][i] = a[r][i] * val % P;
b[r][i] = b[r][i] * val % P;
}
for(int i = 1; i <= n; ++ i){
if(i == r) continue;
val = a[i][c];
for(int j = 1; j <= n; ++ j){
a[i][j] = (a[i][j] - a[r][j] * val % P + P) % P;
b[i][j] = (b[i][j] - b[r][j] * val % P + P) % P;
}
}
++ r;
}
return r <= n;
}
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; ++ i){
for(int j = 1; j <= n; ++ j){
scanf("%lld", &a[i][j]);
if(i == j){
b[i][j] = 1;
}
}
}
if(gauss()){
puts("No Solution");
return 0;
}
for(int i = 1; i <= n; ++ i){
for(int j = 1; j <= n; ++ j){
printf("%lld ", b[i][j]);
}
puts("");
}
return 0;
}
行列式求值
//P7112
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 610;
int n;
ll a[N][N], p;
ll calc(){
ll res = 1, w = 1;
for(int i = 1; i <= n; ++ i){
for(int j = i + 1; j <= n; ++ j){
while(a[i][i]){
ll div = a[j][i] / a[i][i];
for(int k = i; k <= n; ++ k){
a[j][k] = (a[j][k] - div * a[i][k] % p + p) % p;
}
swap(a[i], a[j]), w = -w;
}
swap(a[i], a[j]), w = -w;
}
}
res = w;
for(int i = 1; i <= n; ++ i){
res = res * a[i][i] % p;
}
return (res + p) % p;
}
void solve(){
scanf("%d%lld", &n, &p);
for(int i = 1; i <= n; ++ i){
for(int j = 1; j <= n; ++ j){
scanf("%d", &a[i][j]);
}
}
printf("%lld\n", calc());
}
int main(){
solve();
return 0;
}
//qwq
线性基
const int N = 63;
struct LinearBasis{
ll p[N+10], b[N+10];
int tot = 0, flg_zero = 0;
void ins(ll x){
for(int i = N; i >= 0; -- i){
if(x & (1ll << i)){
if(!p[i]){
p[i] = x;
return;
}
x ^= p[i];
}
}
flg_zero = 1;
return;
}
ll getmx(){
ll ans = 0;
for(int i = N; i >= 0; -- i){
ans = max(ans, ans ^ p[i]);
}
return ans;
}
ll getmn(){
if(flg_zero){
return 0;
}
for(int i = 0; i <= N; ++ i){
if(p[i]){
return p[i];
}
}
}
bool isin(ll x){
for(int i = N; i >= 0; -- i){
if(x & (1ll << i)){
x ^= p[i];
}
}
return x ? 0 : 1;
}
void rebuild(){
tot = 0;
for(int i = 0; i <= N; ++ i){
if(p[i]){
for(int j = i - 1; j >= 0; -- j){
if(p[j] && (p[i] & (1ll << j))){
p[i] ^= p[j];
}
}
b[tot++] = p[i];
}
}
}
ll kthmn(ll k){
k -= flg_zero;
if(!k){
return 0;
}
ll ans = 0;
if(k >= (1ll<<tot)){
return -1;
}
for(int i = 0; i <= N; ++ i){
if(k & (1ll<<i)){
ans ^= b[i];
}
}
return ans;
}
} b;