矩阵方法还是要会的
矩阵
矩阵的基本运算
矩阵加法
最简单了,就是对应数的相加.
如果用i,j来表示行和列
那么就有
减法同理,不作太多的阐述。唯一需要注意事项,当两个矩阵的行和列不相等的时候,求他们的矩阵和或者矩阵差是毫无意义的。只有r1=r2,s1=s2才有加减法的定义。
矩阵乘法(划重点)
稍显复杂,矩阵乘法必须在n行m列和m行p列的两个矩阵中进行运算,否则一样没有意义。
得到一个n行p列的矩阵。
有以下的递推式:
具体细节
根据这个递推式,我们不难得到一个O(n^3)的算法
1 |
|
尽管联赛的要求就是O(n^3)
但是还可以更快
可以试想,当A(i,j)等于0时,那里一整块的结果都是0,不需要继续运算
1 | for (int i = 1; i <= N; i++) |
还有神仙操作的可以优化到O(nm)的操作
贴下代码慢慢理解啦。
高斯费马 树上开花
我们
俯身欣赏.
1 |
|
高斯消元
我们假设有这样一个n阶的可逆矩阵,例如
这样的一个三元一次方程组写成矩阵的形式为
这个矩阵被称作增广矩阵(AUGMENTED MATRIX),最后一列事实上不是系数矩阵而是常数。
这个矩阵可以经过这样的处理。
对于每一行要使得Aii≠0且Aji(j>i)均为0,具体操作
1.来到当前行 以上方矩阵为例子,现在要处理第一行。我们先往下面找到绝对值最大的A(i,r),这里找到是-3,于是交换第1行和第2行.(矩阵变成这个样子,就是交换了一二两行)
对于L1,L2 将L1 3 +L2 2来加减消元,对于第三行,和第二行一样,直接与现在的L1操作。
将L2、L3的首项消成0后继续操作第二行。
以此类推最终得到一个三角矩阵。
差不多就长这个样子。(滑稽
这样其实最后一列已经告诉了我们z=-1。
自下向上迭代即可。
高斯消元代码如下。
1 | void Gauss_Eli(){ |
对于异或^方程组可以用bitset优化.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20bitset<250>A[250]; \\常数项b[i]贴在A[i][n+1]中.
void Gauss_Eli(){
int num;
for (int i=1;i<=n;i++){
if (A[i][i]==0){
num=i;
for (int j=i+1;j<=n;j++)
if (A[j][i]!=0){num=j;break;}
swap(A[num],A[i]);
}
for (int j=i+1;j<=n;j++)
if (A[j][i]!=0) A[j]^=A[i];
}
for (int i=n;i>=1;i--){
ans[i]=A[i][n+1];
for (int j=i;j>=1;j--)
if (A[j][i]!=0)
A[j][n+1]=A[j][n+1]^ans[i];
}
}
题目传送门: