矩阵乘法
(egin{bmatrix} x_0 & 1 end{bmatrix} ast egin{bmatrix} a & 0\ c & 1 end{bmatrix})
O(1)快速乘,见代码
#include <cstdio>
long long MOD;
long long sr;
long long sum(long long a, long long b){
sr=a+b;
if(sr>=MOD) sr-=MOD;
return sr;
}
long long mul(long long a, long long b){
long long k=(long long)((1.0L*a*b)/(1.0L*MOD));
long long ret=a*b-k*MOD;
if(ret<0LL) ret+=MOD;
return ret;
}
long long A, C, X, N, G;
struct Mat{
long long n[2][2];
} Zero, One, Init;
Mat operator * (Mat A, Mat B){
Mat ret=Zero;
for(int i=0;i<2;++i)
for(int j=0;j<2;++j)
for(int k=0;k<2;++k)
ret.n[i][k]=sum(ret.n[i][k], mul(A.n[i][j], B.n[j][k]));
return ret;
}
Mat Pow(Mat a, long long k){
Mat ret=One, t=a;
while(k>0LL){
if(k&1LL) ret=ret*t;
t=t*t;
k>>=1;
}
return ret;
}
int main(){
scanf("%lld%lld%lld%lld%lld%lld", &MOD, &A, &C, &X, &N, &G);
One.n[0][0]=One.n[1][1]=1LL;
Init.n[0][0]=A%MOD;Init.n[0][1]=0LL;
Init.n[1][0]=C%MOD;Init.n[1][1]=1LL;
Init=Pow(Init, N);
long long Ans=sum(mul(Init.n[0][0], X), Init.n[1][0]);
printf("%lld
", Ans%G);
return 0;
}