矩阵快速幂
计算矩阵的幂可以用类似计算数字幂的倍增法,在对数时间内算出结果,这在解决很多线性递推或者二次递推问题时很有用,关键在于根据递推式构造合适的矩阵。
51nod1126 求递推序列的第n项
题面:定义序列f(1)=1, f(2)=1, f(n)=(A*f(n-1)+B*f(n-2))%7,给出A和B,求f(n),其中1<=n<=1e9。
分析:由于n较大,直接递推太慢,考虑构造矩阵通过快速幂来实现。需要注意的是,第1项f(1)不能通过递推来算,只能特判,但这里正好与结果相符,因而可以不用单独处理。
#include <bits/stdc++.h>
using namespace std;
struct matrix {int d[2][2];};
matrix mul(matrix a, matrix b) {
matrix c;
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++) {
int z = 0;
for (int k = 0; k < 2; k++)
z = (z + a.d[i][k] * b.d[k][j]) % 7;
c.d[i][j] = z;
}
return c;
}
int main() {
int n, a, b;
cin >> a >> b >> n;
matrix t = {a, b, 1, 0};
matrix u = {1, 0, 0, 1};
n -= 1;
while (n) {
if (n & 1) u = mul(u, t);
t = mul(t, t);
n /= 2;
}
int ans = (u.d[1][0] + u.d[1][1]) % 7;
if (ans < 0) ans += 7;
cout << ans << endl;
return 0;
}
51nod1113 矩阵快速幂
题面:给出一个n*n的方阵,元素均为正整数,求方阵的m次方,结果中各元素对1e9+7取模。
分析:矩阵快速幂模板题。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
struct matrix {LL d[105][105];};
LL n, m, mod = 1e9+7;
matrix mul(matrix a, matrix b) {
matrix c;
for (LL i = 1; i <= n; i++) {
for (LL j = 1; j <= n; j++) {
LL z = 0;
for (LL k = 1; k <= n; k++)
z = (z + a.d[i][k] * b.d[k][j]) % mod;
c.d[i][j] = z;
}
}
return c;
}
int main() {
cin >> n >> m;
matrix r, t;
for (LL i = 1; i <= n; i++)
for (LL j = 1; j <= n; j++)
r.d[i][j] = i == j ? 1 : 0;
for (LL i = 1; i <= n; i++)
for (LL j = 1; j <= n; j++)
cin >> t.d[i][j];
for (LL b = m; b; b /= 2) {
if (b & 1) r = mul(r, t);
t = mul(t, t);
}
for (LL i = 1; i <= n; i++) {
for (LL j = 1; j <= n; j++)
cout << r.d[i][j] << " ";
cout << endl;
}
return 0;
}