1. 程式人生 > >UVA 10518 How Many Calls(求計算Fibonacci數列第n項時遞迴呼叫次數)

UVA 10518 How Many Calls(求計算Fibonacci數列第n項時遞迴呼叫次數)

題目連結:
UVA 10518 How Many Calls
分析:
根據公式
Cnt[i]=Cnt[i1]+Cnt[i2]+1,且Cnt[0]=Cnt[1]=1.
然後用矩陣快速冪構造矩陣解決就行了。
注意:
輸出必須用”%lld”輸出,用”%I64d”無限WA,簡直了。。。。o(╯□╰)o

//0K 0MS
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace
std; long long n,mod,cases=0; struct Matrix{ int row,col; long long data[10][10]; }; inline void init(Matrix& x) { x.row=x.col=3; memset(x.data,0,sizeof(x.data)); x.data[1][1]=x.data[2][3]=x.data[3][1]=x.data[3][2]=x.data[3][3]=1; } inline Matrix multiply(Matrix a,Matrix b) { Matrix ans; ans.row=a.row,ans.col=b.col; memset
(ans.data,0,sizeof(ans.data)); for(int i=1;i<=ans.row;i++){ for(int j=1;j<=ans.col;j++){ for(int k=1;k<=a.col;k++){ ans.data[i][j]+=a.data[i][k]*b.data[k][j]%mod; ans.data[i][j]%=mod; } } } return ans; } inline
Matrix quick_power(Matrix a,long long n) { Matrix ans,tmp=a; ans.row=ans.col=a.row; memset(ans.data,0,sizeof(ans.data)); for(int i=1;i<=ans.row;i++) ans.data[i][i]=1; while(n){ if(n&1){ ans=multiply(ans,tmp); } tmp=multiply(tmp,tmp); n>>=1; } return ans; } inline void debug(Matrix x) { for(int i=1;i<=x.row;i++){ for(int j=1;j<=x.col;j++){ printf("%lld ",x.data[i][j]); } printf("\n"); } printf("*****************\n"); } int main() { //freopen("Qin.txt","r",stdin); //freopen("Qout.txt","w",stdout); while(~scanf("%lld %lld",&n,&mod)){ if(n==0&&mod==0) break; if(n==0||n==1){ printf("Case %lld: %lld %lld %lld\n",++cases,n,mod,1%mod); continue; } Matrix ans,tmp; init(ans); //debug(ans); ans=quick_power(ans,n-1); //debug(ans); tmp.row=3,tmp.col=1; tmp.data[1][1]=tmp.data[2][1]=tmp.data[3][1]=1; //debug(tmp); tmp=multiply(ans,tmp); //debug(tmp); printf("Case %lld: %lld %lld %lld\n",++cases,n,mod,tmp.data[3][1]%mod); } return 0; }