uva 10518 How Many Calls?(矩阵快速幂)(找规律)

来源:互联网 发布:sql中怎么设置外键 编辑:程序博客网 时间:2024/06/04 19:37

这道题目的题意真是让我很费解,可能英文太差了!尴尬

The fibonacci number is defined by the following recurrence:
fib(0) = 0
fib(1) = 1
fib(n) = fib(n-1)+fib(n-2)
But we're not interested in the fibonacci numbers here. We would like to know how many calls does it take to evaluate the n th fibonacci number if we follow the given recurrence. Since the numbers are going to be quite large, we'd like to make the job a bit easy for you. We'd only need the last digit of the number of calls, when this number is represented in base b.(Check this carefully)

"We would like to know how many calls does it take to evaluate the n th fibonacci number if we follow the given recurrence." 

WTF???

后来才知道是叫我们求递归的次数!难过


通过写一个递归程序并打印出:n,递归次数,Fn。比较可知 fn = Fn*2-1,Fn为第n项斐波拉契数列,fn为要求的递归的次数

之后就是无脑矩阵快速幂了~~


递归程序~

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>
using namespace std;int fn,n,num;int fib(int n,int &cnt) { //加上&才可以在函数中改变变量的值
    cnt++;    if(n == 0) return 0;    if(n == 1) return 1;    fn = fib(n-1,cnt) + fib(n-2,cnt);    return fn;}int main() {    scanf("%d",&n);    for(int i = 0;i <= n;i++) {        int cnt = 0;        int ans = fib(i,cnt);        printf("%2d %8d %8d\n",i,cnt,ans);    }    return 0;}

矩阵快速幂程序~

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define LL long longLL n,m;struct matrix {    LL m[3][3];    matrix () {        memset(m,0,sizeof(m));    }};matrix mul(matrix a,matrix b) {    matrix tmp;    for(int i = 1;i <= 2;i++)        for(int k = 1;k <= 2;k++)            for(int j = 1;j <= 2;j++)                tmp.m[i][j] = (tmp.m[i][j] + a.m[i][k] * b.m[k][j]) % m;    return tmp;}matrix powmul(matrix a,LL n) {    matrix tmp;    tmp.m[1][1] = tmp.m[2][2] = 1;    while(n) {        if(n & 1)            tmp = mul(tmp,a);        a = mul(a,a);        n >>= 1;    }    return tmp;}int main() {    int tt = 0;    while(~scanf("%lld%lld",&n,&m) && (n || m)) {        tt++;        matrix base;        base.m[1][1] = base.m[1][2] = base.m[2][1] = 1;        if(n == 0 || n == 1)            printf("Case %d: %lld %lld 1\n",tt,n,m);        else {            base = powmul(base,n-1);            printf("Case %d: %lld %lld %lld\n",tt,n,m,((base.m[1][1] + base.m[1][2])*2-1) % m);        }    }    return 0;}


0 0
原创粉丝点击