ACM模板
目录
- 高斯消元解线性方程组
- 异或方程组
- bitset优化异或方程组
高斯消元解线性方程组
int a[N][N]
输入矩阵,nnn行,n+1n+1n+1列,下标从0开始
第n+1n+1n+1列表示方程右边的值(n行即n个方程,n列即n个未知数)
int gauss()
返回矩阵的秩(矛盾无解返回-1),并且系数矩阵化为单位矩阵
int a[N][N]
数组第n+1n+1n+1列(下标a[i][n]
)是解xix_ixi
时间复杂度:O(n3)O(n^3)O(n3)
//O(n^3)
#include<bits/stdc++.h>
using namespace std;
const int N=110;
const double eps=1e-6;
int n;
double a[N][N];
int gauss()
{int c,r;for(c=0,r=0;c<n;c++) //枚举每一列{ //找该列绝对值最大的一行 精度int t=r;for(int i=r;i<n;i++)if(fabs(a[i][c])>fabs(a[t][c])) t=i;// 该列都为0 则跳过if(fabs(a[t][c])<eps) continue;// 将该行换到第r行for(int i=c;i<=n;i++) swap(a[r][i],a[t][i]);// 第r行第一项变成1for(int i=n;i>=c;i--) a[r][i]/=a[r][c];// 变成上三角 用第r行去消掉其他所有行的第c列for(int i=0;i<n;i++)if(i!=r&&fabs(a[i][c])>eps) //该行第c列不为0for(int j=n;j>=c;j--)a[i][j]-=a[i][c]*a[r][j];r++;}if(r<n) //非完美阶梯型{for(int i=r;i<n;i++)if(a[i][n]>eps) return -1; // 等式右端不为0return r; //返回秩}return r;
}
异或方程组
第n+1n+1n+1列表示方程右边的值(n行即n个方程,n列即n个未知数)
int gauss
返回矩阵的秩
时间复杂度:O(n3)O(n^3)O(n3)
#include<iostream>
using namespace std;
const int N=110;
int n,a[N][N];
int gauss()
{int r,c;for(c=0,r=0;c<n;c++) //枚举列{int t=r; //找到不为1的那一行for(int i=r;i<n;i++)if(a[i][c]) t=i;if(!a[t][c]) continue; //该列都是0// 不为1的一行换到第r行for(int j=c;j<=n;j++) swap(a[r][j],a[t][j]);// 异或消 第r行消去他们的第c列for(int i=0;i<n;i++)if(i!=r&&a[i][c])for(int j=n;j>=c;j--)a[i][j]^=a[r][j];r++;}if(r<n){for(int i=r;i<n;i++)if(a[i][n]) return -1;return r;}return r;
}
bitset优化异或方程组
bitset的原理大概是将很多数压成一个,从而节省空间和时间,时间复杂度的www通常是32
nnn行mmm列,即nnn个方程mmm个未知数
int gauss
返回矩阵的秩
注意bitset
对于字符串第位在前,而数字第位表示二进制中数字的最低二进制位
时间复杂度:O(n3w)O(\frac{n^3}{w})O(wn3)
#include<bitset>
using namespace std;
const int N=1010;
bitset<N> A[N];
int n,m;
int gauss()
{int r,c;for(c=0,r=0;c<m;c++){int t=r;for(int i=r;i<n;i++)if(A[i][c]) t=i;if(!A[t][c]) continue;swap(A[r],A[t]);for(int i=0;i<n;i++)if(i!=r&&A[i][c])A[i]^=A[r];r++;}if(r<m){for(int i=r;i<n;i++)if(A[i][m]) return -1;return r;}return r;
}