UVA 10518 How Many Calls? (递推+ 矩阵快速幂)
题意问 调用几次fib() 函数:
F(0) =1 F(1)=1 F(2) =3 F(3)= 5 F(4)= 9 F(5)= 15 F(6) =25 F(7)= 41
可以推出 F(N) = F(N-1) + F(N-2) +1
构造 矩阵 A =
代码:
#include <iostream> #include <stdio.h> #include <cmath> #include <string> #include <cstring> typedef long long ll; const int N=100; const int MAXN=3; using namespace std; /* f(n)= f(n-2)+ f(n-1) +1 */ ll n,MOD; struct Matrix{ ll arr[N][N]; void init() { memset(arr,0,sizeof(arr)); for(int i=0;i<MAXN;i++) arr[i][i]=1;//初始化 } void iinit() { memset(arr,0,sizeof(arr)); arr[0][0]=arr[0][1]=arr[0][2]=arr[1][0]=arr[2][2]=1; } }A; Matrix mul(Matrix X,Matrix Y)// 矩阵乘法 { Matrix ans; for(int i=0;i<MAXN;i++) for(int j=0;j<MAXN;j++){ ans.arr[i][j]=0; for(int k=0;k<MAXN;k++){ ans.arr[i][j]+=X.arr[i][k]*Y.arr[k][j]; ans.arr[i][j]%=MOD; } } return ans; } Matrix Q_pow(Matrix B,ll n)// 矩阵快速幂 { Matrix ans; ans.init(); while(n) { if(n&1) ans=mul(ans,B); n>>=1; B=mul(B,B); } return ans; } int main() { int cont=0; //freopen("input.txt","r",stdin); while(cin>>n>>MOD) { if(MOD==0) break; Matrix ans; ans.iinit(); if(n<2) printf("Case %d: %lld %lld %d\n",++cont,n,MOD,1%MOD); else { ans=Q_pow(ans,n-1); ll res; res=(ans.arr[0][0]+ans.arr[0][1]+ans.arr[0][2])%MOD; printf("Case %d: %lld %lld %lld\n",++cont,n,MOD,res%MOD); } } return 0; }
12
岂曰无衣?与子同袍。王于兴师,修我戈矛。与子同仇!
岂曰无衣?与子同泽。王于兴师,修我矛戟。与子偕作!
岂曰无衣?与子同裳。王于兴师,修我甲兵。与子偕行!