UVA 10518 How Many Calls?

来源:互联网 发布:单片机中文字库 编辑:程序博客网 时间:2024/05/29 11:07

题目链接:http://acm.hust.edu.cn/vjudge/problem/24146


题意:已知f(0),f(1),fi = fi-1 + fi-2,问用递归式计算fn需要调用函数多少次?


思路:调用fn自己算一次,在fn里面还需要调用fn-1 和 fn-2,所以把他们的次数加一起就是总次数。

所以Fi = Fi-1 + Fi-2 + 1 ,  F0 = F1 = 1.


#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <cstdlib>#include <iostream>#include <algorithm>#include <stack>#include <map>#include <set>#include <vector>#include <sstream>#include <queue>#include <utility>using namespace std;#define rep(i,j,k) for (int i=j;i<=k;i++)#define Rrep(i,j,k) for (int i=j;i>=k;i--)#define Clean(x,y) memset(x,y,sizeof(x))#define LL long long#define ULL unsigned long long#define inf 0x7fffffffLL n;int mod;struct node{    LL a[3][3];    void P()    {        Clean(a,0);        a[0][1] = 1;        a[1][0] = 1;        a[1][1] = 1;        a[2][1] = 1;        a[2][2] = 1;    }    void E()    {        Clean(a,0);        rep(i,0,2) a[i][i] = 1;    }};node multi( node &x , node &y ){    node ans;    rep(i,0,2)        rep(j,0,2)        {            ans.a[i][j] = 0;            rep(k,0,2)                ans.a[i][j] = ( ans.a[i][j] + ( x.a[i][k] * y.a[k][j] ) % mod ) % mod;        }    return ans;}LL solve(){    if ( n == 0 || n == 1 ) return 1 % mod;    node temp , ans;    temp.P();    ans.E();    while( n )    {        if ( n & 1 ) ans = multi( ans , temp );        temp = multi( temp , temp );        n >>= 1;    }    LL S = 0;    rep(i,0,2) S = ( S + ans.a[i][0] ) % mod;    return S;}int main(){    int T = 0;    while( scanf("%lld %d",&n,&mod) == 2 )    {        if ( n == 0 && mod == 0 ) break;        printf("Case %d: %lld %d " , ++T , n , mod );        printf("%lld\n",solve());    }    return 0;}



0 0
原创粉丝点击