题目传送门:Problem - 5667
Holion August will eat every thing he has found.
Now there are many foods,but he does not want to eat all of them at once,so he find a sequence.
He gives you 5 numbers n,a,b,c,p,and he will eat fn foods.But there are only p foods,so you should tell him mod p.
Input
The first line has a number,T,means testcase.
Each testcase has 5 numbers,including n,a,b,c,p in a line.
1≤T≤10,1≤n≤1018,1≤a,b,c≤109,p is a prime number,and p≤109+7.
Output
Output one number for each case,which is fn mod p.
样例输入:
1
5 3 3 3 233
样例输出:190
题目大意:
给你对应的函数参数以及n,计算.
解题思路:
本题是一个矩阵快速幂问题,我们令,那么我们就有以下式子:
,此时
就是我们答案的幂,答案为
,由于模数p为一个质数,那么由欧拉定理
,所以我们计算
的时候是对(p-1)取模,同时前面的公式,我们就可以推出矩阵快速幂的对应矩阵,为:
,递推一下,就有了:
,接着按矩阵乘法算出
,极为幂,接着在用快速幂,算出答案,此时取模运算的时候又是对p取模,不要搞混,算出即为答案。
AC代码:
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
ll n,a,b,c,p;
struct node
{
ll a[5][5];
}res,ans;
struct node mul(struct node a,struct node b)//矩阵相乘函数,按个人喜好写就行
{
struct node c;
memset(c.a, 0, sizeof(c.a));
for (int i=1; i<=3; i++) {
for (int j=1; j<=3; j++) {
for (int k=1; k<=3; k++) {
c.a[i][j]+=a.a[i][k]*b.a[k][j];
c.a[i][j]%=p;
}
}
}
return c;
}
void qsm_matr()
{
n-=2;
memset(res.a, 0, sizeof(res.a));
memset(ans.a, 0, sizeof(ans.a));
for (int i=1; i<=3; i++) ans.a[i][i]=1;//初始化
res.a[1][1]=c;
res.a[1][2]=1;
res.a[1][3]=b;
res.a[2][1]=1;
res.a[3][3]=1;
while(n)
{
if(n&1) ans=mul(ans, res);
res=mul(res, res);
n>>=1;
}
}
ll qsm(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1) res=res*a%p;
a=a*a%p;
b>>=1;
}
return res;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld%lld%lld%lld",&n,&a,&b,&c,&p);
if(n==1) printf("1\n");
else if (n==2) printf("%lld\n",qsm(a, b));
else{
if(a%p==0)
{
printf("0\n");
continue;
}
p--;//计算幂对(p-1)取余
qsm_matr();//矩阵快速幂
ll k=(ans.a[1][1]*b+ans.a[1][3])%p;//得到幂
p++;//p再加回来
printf("%lld\n",qsm(a, k));
}
}
return 0;
}