题意:Fibonacci 数列是大家的老朋友了
Fib[1]=1, Fib[2]=1, Fib[3]=2……Fib[n]= Fib[n-1]+ Fib[n-2]
p是一个不甘寂寞的素数。某日它找到Fibonacci 数列,跳到Fibonacci 数列头上玩了起一个传说中的游戏。于是我们看到:
Fib[a]^p+ Fib[a+1]^p+ Fib[a+2]^p……….. + Fib[b]^p
好了,我们的问题来了,求上述表达式的值(即fab[i]的p次方之和,b>=i>=a),结果模p。
输入三个整数a、b、p,满足:
1000,000,000>a>0
1000,000,000>b>a
1000,000,000 > p
输出 一个整数。题目中要求表达式 模p 的结果
解析:由于欧拉定理:(a^α(p))%p=1; 其中α(p)为p的欧拉函数值若α(p) 中p为质数那么α(p)=p-1
此题化简可得fib(i)^p%p=(a^(p-1))*a%p=a%p;
还有斐波那契数列的性质:f(0)+f(1)+……+f(n)=f(2+n)-1
又有斐波那契数列的公式f(0)+f⑴+f⑵+…+f(n)=f(n+2)-1。所以可以用矩阵连乘
#include<iostream>
using namespace std;
__int64 mod,sum,sta,end;
void mul(__int64 a[][2],__int64 b[][2])
{
__int64 i,j,k,c[2][2];
memset(c,0,sizeof(c));
for ( i=0;i<2;i++ )
for ( j=0;j<2;j++ )
for ( k=0;k<2;k++ )
c[i][k]=(c[i][k]+a[i][j]*b[j][k]);
for ( i=0;i<2;i++ )
for ( j=0;j<2;j++ )
a[i][j]=c[i][j]%mod;
}
__int64 solve(__int64 n)
{
__int64 s[2][2],t[2][2],i,j;
for ( i=0;i<2;i++ )
for ( j=0;j<2;j++ )
s[i][j]=(i==j);
t[0][0]=t[0][1]=t[1][0]=1;
t[1][1]=0;
while ( n )
{
if ( n&1 )
mul(s,t);
// if(n>=st-2 && n<=ed-2)
// sum+=(s[0][0]+s[1][0])%mod;
mul(t,t);
// if(n>=st-2 && n<=ed-2)
// sum+=(s[0][0]+s[1][0])%mod;
n>>=1;
}
return ((s[0][0]+s[1][0]));
}
int main()
{
__int64 p;
while ( scanf("%I64d%I64d%I64d",&sta,&end,&p)!=EOF)
{
mod=p;
sum=0;
__int64 aaa=solve(sta-1)-1;
// cout<<aaa<<endl;
__int64 bbb=solve(end)-1;
// cout<<bbb<<endl;
bbb=((bbb-aaa)%p+p)%p;//这里在mod完以后有可能bbb小于aaa所以加p在mod p处理
printf("%I64d\n",bbb);
}
return 0;
}
本文介绍了一种解决斐波那契数列求和问题的方法,利用矩阵快速幂来高效计算指定区间内斐波那契数列元素的p次方模p的值。文中详细解释了如何通过矩阵运算实现快速计算,并给出了完整的C++代码实现。

2900

被折叠的 条评论
为什么被折叠?



