CC

自然万物都趋向从有序变得无序

0%

How Many Calls? UVA - 10518 矩阵快速幂

题目链接: 点我

题目


题意:

给你fibonacci数列怎么求的,然后问你求f(n) = f(n - 1) + f(n - 2)需要多少次调用,并且这个数很大,取模一个进制的数。

思路:

我们要知道调用次数F(n) = f(n)* 2 - 1这个规律,那么这题就可以解了,矩阵快速幂跑一边即可.

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;

typedef long long LL;
LL n, b;

struct mat {
LL a[3][3];
mat(){memset(a, 0,sizeof(a)); }
mat operator *(const mat q){
mat c;
for(int i = 1; i <= 2; ++i)
for(int j = 1; j <= 2; ++j)
if(a[i][j])
for(int k = 1; k<= 2; ++k){
c.a[i][k] += a[i][j] * q.a[j][k];
if(c.a[i][j] >= b) c.a[i][k] %= b;
}return c;
}
};

mat qpow(mat x, LL n){
mat ans;
ans.a[1][1] = ans.a[2][2] = 1;
while(n){
if(n&1) ans =ans * x;
x = x * x;
n >>= 1;
}return ans;
}

int main(){
int kase = 0;
while(scanf("%lld %lld", &n, &b) != EOF&&(n||b)){
mat ans;
ans.a[1][1] =ans.a[1][2] = ans.a[2][1] = 1;
ans =qpow(ans, n+1);
LL sum = (ans.a[2][1] * 2 - 1 + b) % b;
printf("Case %d: %lld %lld %lld\n",++kase, n, b, sum);
}return 0;
}