题目链接: 点我
题目
题意:
给你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; }
|