题目地址点击打开链接
代码如下
#include <cstdio>
#include <cstring>
using namespace std;
__int64 a, b, n, m;
struct Matrix{
int column;
int row;
__int64 a[3][3];
void clear()
{
column = row = 0;
memset(a, 0, sizeof(a));
}
Matrix operator * (const Matrix& B) const
{
Matrix C;
C.clear();
C.row = row;
C.column = B.column;
for (int i = 0; i < C.row; ++i)
for (int j = 0; j < C.column; ++j)
for (int k = 0; k < column; ++k)
C.a[i][j] = ((C.a[i][j] + a[i][k] * B.a[k][j]) % m + m)%m ;
return C;
}
};
Matrix mat_pow(Matrix A, __int64 pow_n)
{
Matrix C;
C.clear();
C.column = C.row = A.column;
for (int i = 0; i < C.column; ++i)
C.a[i][i] = 1;
while (pow_n)
{
if (pow_n & 1)
C = C * A;
A = A * A;
pow_n >>= 1;
}
return C;
}
Matrix A, B, C;
int main(void)
{
while (scanf("%I64d%I64d%I64d%I64d", &a, &b, &n, &m) != EOF)
{
A.clear();
B.clear();
C.clear();
A.column = A.row = 2;
A.a[0][0] = 2 * a;
A.a[0][1] = b - a * a;
A.a[1][0] = 1;
A.a[1][1] = 0;
B = mat_pow(A, n - 1);
C.row = 2;
C.column = 1;
C.a[0][0] = 2 * a;
C.a[1][0] = 2;
B = B * C;
printf("%I64d\n", B.a[0][0]);
}
}