模运算
(a + b) % mod = (a % mod) + (b % mod);
(a - b) % mod = (a % mod) - (b % mod);
(a * b) % mod = (a % mod) * (b % mod);
(a / b) % mod = (a % mod) / (b % mod); 四个里面这个是不对的,比如100 / 50 在mod 2
快速幂
int pow_fast(int a, int n) {
int ans = 1;
while (n--) {
if (n & 1) ans = ans * a;
a = a * a;
n >>= 1;
}
return ans;
}
矩阵快速幂
#include <bits/stdc++.h>
using namespace std;
const int N = 10;
const int INF = 0x3f;
int n;
struct matrix{
int m[N][N];
matrix() {
memset(m, INF, sizeof m);
}
// int &operator[][](int i, int j){
// return m[i][j];
// } 有没有高手能够重载[][]的,评论告诉我,我不会啊
};
matrix operator * (const matrix& a, const matrix& b) {
// 设置一个新矩阵
matrix c;
// 下面的i,j,k交换位置没有关系
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
for (int k = 1; k <= n; k++) { // i k k j
c.m[i][j] += a.m[i][k] * b.m[k][j];
}
}
}
return c;
}
matrix pow_matrix(matrix a, int n) {
// 定义一个单位矩阵
matrix ans;
for (int i = 1; i <= n; i++) {
a.m[i][i] = 1;
}
// 快速幂
while (n--) {
if (n & 1) ans = ans * a;
a = a * a;
n >>= 1;
}
return ans;
}
矩阵的应用:
1、加速递推:(这个看看做题时候能不能想到)
斐波那契数列
计算矩阵幂的和
文字太多,自己看。
重点是S这个矩阵,利用矩阵快速幂求S的k次方,然后左下角的就是了
例6.2 Matrix power series(poj 3233)
问题描述:给定一个nXn的矩阵A和一个正整数k,求幂矩阵和 sum(k)=A小A2十A3十…十A、。
输入:第1行输入3个正整数n(n<30)、k(k<10)和m(m<10);后面n行中每行输入n个比32767小的非负整数,按行给出矩阵A的元素。输出:输出幂矩阵和sum(k),并对m 取模。
2、求两点间只经过n条边的最短路径长度
用邻接矩阵存两个点之间的权值,然后对这个矩阵求幂(公式要换一点点)
#include <bits/stdc++.h>
using namespace std;
const int N = 10;
const int INF = 0x3f;
int n;
struct matrix{
int m[N][N];
matrix() {
memset(m, INF, sizeof m);
}
// int &operator[][](int i, int j){
// return m[i][j];
// } 有没有高手能够重载[][]的,评论告诉我,我不会啊
};
matrix operator * (const matrix& a, const matrix& b) {
// 设置一个新矩阵
matrix c;
// 进行乘法,因为是最短路径,所以min
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
for (int k = 1; k <= n; k++) { // i k k j
c.m[i][j] = min(c.m[i][j], a.m[i][k] + b.m[k][j]);
}
}
}
return c;
}
matrix pow_matrix(matrix a, int n) {
// 定义一个单位矩阵
matrix ans;
for (int i = 1; i <= n; i++) {
a.m[i][i] = 1;
}
// 快速幂
while (n--) {
if (n & 1) ans = ans * a;
a = a * a;
n >>= 1;
}
return ans;
}
int main() {
int n, t, s, e;
matrix a;
while (t--) {
int u, v, w; cin >> w >> u >> v;
if(!Hash[u]) Hash[u] = ++cnt;
if(!Hash[v]) Hash[v] = ++cnt;
a.a[Hash[u]][Hash[v]] = a.m[Hash[v]][Hash[u]] = w;
}
martix ans = pow_matrix(a, n);
printf("%d",ans.m[Hash[s]][Hash[e]]);
return 0;
}
练习:
矩阵加速递推:洛谷p 1349 1939 1306 2044 5175 hdu 4990 4565 4965 4549 4686 5015
路径问题:hdu 2157
矩阵快速幂:洛谷 p 3390 1939 4783 1962 1349 4000 3758 4967 5343 5337 5303