【HDU 2855】 Fibonacci Check-up (矩阵乘法)
Fibonacci Check-up
Problem DescriptionEvery ALPC has his own alpc-number just like alpc12, alpc55, alpc62 etc.
As more and more fresh man join us. How to number them? And how to avoid their alpc-number conflicted?
Of course, we can number them one by one, but that’s too bored! So ALPCs use another method called Fibonacci Check-up in spite of collision.
First you should multiply all digit of your studying number to get a number n (maybe huge).
Then use Fibonacci Check-up!
Fibonacci sequence is well-known to everyone. People define Fibonacci sequence as follows: F(0) = 0, F(1) = 1. F(n) = F(n-1) + F(n-2), n>=2. It’s easy for us to calculate F(n) mod m.
But in this method we make the problem has more challenge. We calculate the formula , is the combination number. The answer mod m (the total number of alpc team members) is just your alpc-number.
InputFirst line is the testcase T.
Following T lines, each line is two integers n, m ( 0<= n <= 10^9, 1 <= m <= 30000 )
OutputOutput the alpc-number.
Sample Input2 1 30000 2 30000
Sample Output1 3
【题意】
求S(n)=∑C[k][n]*Fibonacci(k) mod m(0<=k<=n)
( 0<= n <= 10^9, 1 <= m <= 30000 )
【分析】
组合数和斐波那契数列都是很有特点的东西,然而我想了一会儿还是没有想出来。
现在又懂得了一点,能写出递推式,像斐波那契数列一样的,它的第k项其实可以表示成矩阵的幂,即A^k,把它当成数一样考虑就很方便。
对于组合数,二项式定理啊真是太厉害了。。终于有点懂母函数的思想啊....
图片转自:http://blog.csdn.net/hzh_0000/article/details/38171903
其实还有第二种方法,我没打,感觉我不太可能推出来。。
第一种方法代码如下:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 #include<cmath> 8 using namespace std; 9 10 struct node 11 { 12 int a[5][5]; 13 }t[5]; 14 15 int n,m; 16 17 void init() 18 { 19 t[0].a[1][1]=1;t[0].a[1][2]=1; 20 t[0].a[2][1]=1;t[0].a[2][2]=2; 21 } 22 23 void mul(int x,int y,int z) 24 { 25 for(int i=1;i<=2;i++) 26 for(int j=1;j<=2;j++) 27 { 28 t[2].a[i][j]=0; 29 for(int k=1;k<=2;k++) 30 t[2].a[i][j]=(t[2].a[i][j]+t[y].a[i][k]*t[z].a[k][j])%m; 31 } 32 t[x]=t[2]; 33 } 34 35 void get_un() 36 { 37 memset(t[1].a,0,sizeof(t[1].a)); 38 for(int i=1;i<=2;i++) t[1].a[i][i]=1; 39 } 40 41 void qpow(int b) 42 { 43 get_un(); 44 while(b) 45 { 46 if(b&1) mul(1,0,1); 47 mul(0,0,0); 48 b>>=1; 49 } 50 } 51 52 int main() 53 { 54 int T; 55 scanf("%d",&T); 56 while(T--) 57 { 58 scanf("%d%d",&n,&m); 59 init(); 60 qpow(n); 61 printf("%d\n",t[1].a[1][2]); 62 } 63 return 0; 64 }
2016-09-28 14:10:22