这道题不得不说出的很巧妙,需要通过一个题目的条件来推出矩阵递推式
过程不多说了,递推式出来就很好做了,但是要注意用long long 还有矩阵存在负值,需要(x%mod+mod)%mod
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL __int64
__int64 a,b,n,m;
struct matrix {
LL m[3][3];
matrix() {
memset(m,0,sizeof(m));
}
};
matrix mul(matrix a,matrix b) {
matrix tmp;
for(int i = 1;i <= 2;i++)
for(int j = 1;j <= 2;j++)
for(int k = 1;k <= 2;k++)
tmp.m[i][j] = ((tmp.m[i][j] + a.m[i][k] * b.m[k][j]) % m + m) % m;
return tmp;
}
matrix powmul(matrix a,int n) {
matrix tmp;
for(int i = 1;i <= 2;i++)
tmp.m[i][i] = 1;
while(n) {
if(n & 1)
tmp = mul(tmp,a);
a = mul(a,a);
n >>= 1;
}
return tmp;
}
int main() {
while(scanf("%I64d%I64d%I64d%I64d",&a,&b,&n,&m) != EOF) {
matrix base;
base.m[1][1] = 2*a % m;
base.m[1][2] = -(((a*a) - b) % m);
base.m[2][1] = 1;
if(n == 1)
printf("%I64d\n",(2*a) % m);
else if(n == 2)
printf("%I64d\n",((a*a + b)<<1) % m);
else {
base = powmul(base,n-2);
printf("%I64d\n",(((((a*a + b)<<1) % m) * base.m[1][1] + 2*a * base.m[1][2]) % m + m) % m);
}
}
return 0;
}