luogu 传送门
我们可以设一个矩阵A={p , 1
q , 0}
ans矩阵{a2 , a1},用ans矩阵*A矩阵的n-2次方,ans[1][1]就是答案了。
正确性自己在纸上画一画就显而易见了。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#define LL long long
using namespace std;
LL p,q,a1,a2,n,MOD;
LL A[3][3];
LL B[3][3];
LL ans[2][2];
LL bak[3][3];
void Fast_Pow()
{
while(n)
{
if(n%2)
{
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
bak[i][j]=B[i][j],B[i][j]=0;
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
for(int k=1;k<=2;k++)
B[i][j]=(B[i][j]+bak[i][k]*A[k][j]%MOD)%MOD;
}
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
bak[i][j]=A[i][j],A[i][j]=0;
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
for(int k=1;k<=2;k++)
A[i][j]=(A[i][j]+bak[i][k]*bak[k][j]%MOD)%MOD;
n/=2;
}
}
int main()
{
scanf("%lld%lld%lld%lld%lld%lld",&p,&q,&a1,&a2,&n,&MOD);
A[1][1]=p,A[2][1]=q,A[1][2]=1;
B[1][1]=p,B[2][1]=q,B[1][2]=1;
n--;ans[1][1]=a2,ans[1][2]=a1;
if(n==1) {printf("%lld",a1%MOD);return 0;}
if(n==2) {printf("%lld",a2%MOD);return 0;}
n-=2;
Fast_Pow();
ans[1][1]=(ans[1][1]*B[1][1]%MOD+ans[1][2]*B[2][1]%MOD)%MOD;
printf("%lld",ans[1][1]);
return 0;
}