题意: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; }