题目链接:https://vjudge.net/contest/347398#problem/G
分析:
1.如何构建矩阵和斐波那契数列联系起来。
f[0]=a
f[1]=b
f[2]=ab
f[3]=ab^2
f[4]=a^2 b^3
f[5]=a^3 b^5
f[6]=a^5 b^8
…
由此可见a和b的系数和斐波那契数列有联系
构造矩阵
1 1
1 0
加上单位矩阵
1 0
0 1
用矩阵快速幂表示出斐波那契的第n项的值。
此题结果对1e9+7取余,考虑1e9+7为素数
在求解a和b系数的过程,引入费马小定理进行优化
费马小定理:
若p为素数,gcd(a,p)=1,则a^(p-1)=1(mod p)
推广:p为素数,x^p-x(x为任意正整数)必定能被p整除(相当于1从右边移到左边,没有余数了)
费马小定理的降幂处理:
a^b mod p若符合费马小定理的使用条件,则
a^b mod p=a^ (b%(p-1)) mod p
把b转化为p-1的整数倍+余数。因为a^(p-1) mod p=1,所以可以达到降幂处理的效果。
a p不互质:
a^b进行降幂处理:
a^b=a ^b(mod n) b<phi(n)
a^b=a ^(b%phi(n)+phi(n))(mod n) b>=phi(n)
phi(n) 为n的欧拉函数
代码:
#include<cstdio>
#include<cmath>
#include<iostream>
#include<stdlib.h>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int mod=1000000007;
struct node
{
LL m[3][3];
} first,second;
node update(node x,node y)
{
node temp;
for(int i=1; i<=2; i++)
{
for(int j=1; j<=2; j++)
{
temp.m[i][j]=0;
for(int k=1; k<=2; k++)
{
temp.m[i][j]+=x.m[i][k]*y.m[k][j];
temp.m[i][j]%=(mod-1);
}
}
}
return temp;
}
void Quick_Mi(LL res)
{
for(int i=1; i<=2; i++)
for(int j=1; j<=2; j++)
{
if(i==j)
first.m[i][j]=1;
else
first.m[i][j]=0;
}
second.m[1][1]=1;
second.m[1][2]=1;
second.m[2][1]=1;
second.m[2][2]=0;
while(res)
{
if(res&1)
first=update(first,second);
second=update(second,second);
res>>=1;
}
}
LL solve(LL num,LL res)
{
LL sum=1;
while(res)
{
if(res&1)
sum=(sum*num)%mod;
num=(num*num)%mod;
res>>=1;
}
return sum;
}
int main()
{
LL a,b,n;
while(~scanf("%lld%lld%lld",&a,&b,&n))
{
if(n==0)
{
cout<<a<<endl;
continue;
}
if(n==1)
{
cout<<b<<endl;
continue;
}
if(a==0||b==0)
{
cout<<0<<endl;
continue;
}
Quick_Mi(n);/*快速幂求其系数*/
LL fb=first.m[1][2]%(mod-1);/*a和b的系数在其矩阵中表示的位置*/
LL fa=first.m[2][2]%(mod-1);
LL t1=solve(b,fb);
LL t2=solve(a,fa);
LL tail=t1*t2%mod;
cout<<tail<<endl;
}
return 0;
}