斐波那契数列
题目链接:ybt高效进阶6-1-2
题目大意
求斐波那契数列的第 i 项。
思路
一开始的矩阵:
1 | 1 |
---|
然后乘 i i i 次转移矩阵:
0 | 1 |
---|---|
1 | 1 |
然后用矩阵快速幂就可以了。
代码
#include<cstdio>
#include<cstring>
#define ll long long
#define mo 1000000007
using namespace std;
struct matrix {
int n, m;
ll a[2][2];
}ans, one, b;
ll n, y;
matrix operator *(matrix x, matrix y) {
matrix z;
z.n = x.n; z.m = y.m;
memset(z.a, 0, sizeof(z.a));
for (int k = 0; k < x.m; k++)
for (int i = 0; i < x.n; i++)
for (int j = 0; j < y.m; j++)
z.a[i][j] = (z.a[i][j] + (x.a[i][k] * y.a[k][j]) % mo) % mo;
return z;
}
matrix jzksm(matrix x, ll y) {
matrix re;
re = one;
while (y) {
if (y & 1) re = re * x;
x = x * x;
y >>= 1;
}
return re;
}
int main() {
one.n = one.m = 2;
for (int i = 0; i < one.n; i++) one.a[i][i] = 1;
scanf("%lld", &n);
if (n == 1) {
printf("1");
return 0;
}
ans.n = 1; ans.m = 2;
ans.a[0][0] = ans.a[0][1] = 1;
b.n = b.m = 2;
b.a[0][0] = 0; b.a[0][1] = 1;
b.a[1][0] = 1; b.a[1][1] = 1;
ans = ans * jzksm(b, n - 1);
printf("%lld", ans.a[0][0]);
return 0;
}