UVA 10518 How Many Calls?

 

设g(x)为n=x时的调用次数,有Fabonacci数列递推式可以得到

g(x)=g(x-1)+g(x-2)+1,(f(x)要调用一次,所以要加1)。

转换为矩阵形式

即,

g(1)和g(0)均为1。

使用矩阵快速幂计算结果。

 

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <map>
 4 #include <vector>
 5 #include <functional>
 6 #include <string>
 7 #include <cstring>
 8 #include <queue>
 9 #include <set>
10 #include <cmath>
11 #include <cstdio>
12 using namespace std;
13 #define IOS ios_base::sync_with_stdio(false)
14 typedef long long LL;
15 const int INF=0x3f3f3f3f;
16 
17 int modnum;
18 const int maxn=5;
19 typedef struct matrix{
20     int v[maxn][maxn];
21     void init(){memset(v,0,sizeof(v));}
22 }M;
23 M a,b;
24 M mul_mod(const M &a,const M &b,int L,int m,int n)
25 {
26     M c; c.init();
27     for(int i=0;i<L;i++){
28         for(int j=0;j<n;j++){
29             for(int k=0;k<m;k++)//注意j,k范围
30                 c.v[i][j]=(c.v[i][j]+(a.v[i][k]*b.v[k][j]%modnum))%modnum;
31         }
32     }
33     return c;
34 }
35 M power(M x,int L,LL p)
36 {
37     M tmp; tmp.init();
38     for(int i=0;i<L;i++)
39         tmp.v[i][i]=1;
40     while(p){
41         if(p&1) tmp=mul_mod(x,tmp,L,L,L);
42         x=mul_mod(x,x,L,L,L);
43         p>>=1;
44     }
45     return tmp;
46 }
47 inline void init()
48 {
49     a.init();
50     a.v[0][0]=a.v[0][1]=a.v[0][2]=a.v[1][0]=a.v[2][2]=1;
51     b.init();
52     b.v[0][0]=b.v[1][0]=b.v[2][0]=1;
53 }
54 int main()
55 {
56     LL n;
57     int ca=0;
58     while(scanf("%lld%d",&n,&modnum)==2&&n+modnum){
59         init();
60         if(n<2){printf("Case %d: %lld %d %d\n",++ca,n,modnum,1%modnum); continue;}
61         a=power(a,3,n-1);
62         a=mul_mod(a,b,3,3,1);
63         printf("Case %d: %lld %d %d\n",++ca,n,modnum,a.v[0][0]);
64     }
65 }
View Code

 

posted @ 2016-07-22 18:42  Cumulonimbus  阅读(237)  评论(0编辑  收藏  举报