2014年蓝桥杯 —— 斐波那契
研究了矩阵的快速幂,敲了一下,两个样例是过了,但是只给了第一个样例的分。
真的搞不懂什么个鬼。。。
代码仅供参考(不是AC代码):
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <map>
#include <sstream>
#include <queue>
#include <stack>
#include <vector>
#define INF 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define For(a,b) for(int i = a;i<b;i++)
#define ll long long
#define MAX_N 100010
using namespace std;
typedef vector<int> vec;
typedef vector<vec> mat;
ll M;
mat mul(mat &A,mat &B){
mat C(A.size(),vec(B[0].size()));
for(int i = 0; i<A.size(); i++)
{
for(int k = 0; k<B.size(); k++)
{
for(int j = 0; j<B[0].size(); j++)
{
C[i][j] = (C[i][j] + A[i][k] * B[k][j]);
}
}
}
return C;
}
mat mul2(mat &A,mat &B){
mat C(A.size(),vec(B[0].size()));
for(int i = 0; i<A.size(); i++)
{
for(int k = 0; k<B.size(); k++)
{
for(int j = 0; j<B[0].size(); j++)
{
C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % M;
}
}
}
return C;
}
mat pow(mat A,ll p,int r){
mat B(A.size(),vec(A[0].size()));
for(int i = 0; i<A.size(); i++){
B[i][i] = 1;
}
while(p>0)
{
if(p & 1)
{
if(r)
B = mul2(B,A);
else B = mul(B,A);
}
if(r)
A = mul2(A,A);
else A = mul(A,A);
p >>= 1;
}
return B;
}
ll f(ll p,int r){
mat A(2,vec(2));
A[0][0] = 1,A[0][1] = 1;
A[1][0] = 1,A[1][1] = 0;
A = pow(A,p,r);
ll con = (ll)A[1][0];
return con;
}
int main()
{
ll n,m,p;
while(~scanf("%lld %lld %lld",&n,&m,&p))
{
M = f(m,0);
//printf("%lld\n",x[1000]);
ll ans = 0;
for(int i = 1; i<=n; i++)
{
ans += (f(i,1));
}
ans %= M;
ans %= p;
printf("%lld\n",ans);
}
return 0;
}