您的位置:首页 > 其它

[hdu2855][矩阵乘法]Fibonacci Check-up

2018-02-27 16:31 239 查看
Fibonacci Check-up

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 1660 Accepted Submission(s): 937

Problem Description

Every 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.

Input

First line is the testcase T.

Following T lines, each line is two integers n, m ( 0<= n <= 10^9, 1 <= m <= 30000 )

Output

Output the alpc-number.

Sample Input

2

1 30000

2 30000

Sample Output

1

3

Source

2009 Multi-University Training Contest 5 - Host by NUDT

sol:

求解C(n,0)*f(0)+C(n,1)*f(1)……C(n,n)*f(n)

打表发现可以递推,g[i]=g[i-1]*3+g[i-2]

标算做法:

考虑二项式定理,(a+b)^n=C(n,0)*a^n+C(n,1)*a^n-1*b+…..+C(n,n)*b^n

和上面要求的式子非常相似,如果a是1,b^i表示f(i)的话,这个式子就和上面完全等价了。就相当于求矩阵(1+b)^n。其中1是单位矩阵。b是fib的转移矩阵,因为b^n代表的也就是f(n)

那么(1+b)^n=∑iC(n,i)∗bi∗1n−i∑iC(n,i)∗bi∗1n−i

接下来从矩阵的角度解释下数学上是不是对的

考虑矩阵满足结合律,分配律,显然矩阵的二项式是成立的。先把单位矩阵乘完,再乘b^i,显然这个东西就是b^i,然后C(n,i)*b^i的话,就相当于把整个矩阵的树都乘上了C(n,i),比如我们f(n)存在b[1,1]里面,那么你的答案就在c[1,1],其中c=(1+b)^n,最后外面的那层∑∑就相当于是把这些乘完C(n,i)的fib矩阵给累加了起来。

方法二

#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long ll;
typedef double s64;
int n,m;
inline int read()
{
char c;
int res,flag=0;
while((c=getchar())>'9'||c<'0') if(c=='-')flag=1;
res=c-'0';
while((c=getchar())>='0'&&c<='9') res=(res<<3)+(res<<1)+c-'0';
return flag?-res:res;
}
const int N=3;
int a

,b

,tmp

,pyz;
inline void simplex(int a

)
{
memset(tmp,0,sizeof(tmp));
for(int i=1;i<=2;++i)
for(int j=1;j<=2;++j)
for(int k=1;k<=2;++k)
tmp[i][j]=(tmp[i][j]+a[i][k]*b[k][j]%pyz)%pyz;
for(int i=1;i<=2;++i)
for(int j=1;j<=2;++j)
a[i][j]=tmp[i][j];
}
inline int ksm(int t)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
a[1][2]=1;
b[1][1]=1;
b[1][2]=1;
b[2][1]=1;
b[2][2]=2;
while(t)
{
if(t&1) simplex(a);
simplex(b);
t>>=1;
}
return a[1][1];
}
inline void solve()
{
n=read();
pyz=read();
printf("%d\n",ksm(n));
}
int main()
{
//  freopen("2855.in","r",stdin);
//  freopen(".out","w",stdout);
int T=read();
while(T--) solve();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: