HDU-4565 So Easy! 公式化简
题意:非常简单,就是求一个表达式的最后结果。
解法:http://blog.csdn.net/magic____/article/details/9021169
代码如下:
#include <cstdlib> #include <cstring> #include <cstdio> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; LL a, b, n, m; struct Matrix { int r, c; int a[2][2]; void unit() { memset(a, 0, sizeof (a)); for (int i = 0; i < r; ++i) { a[i][i] = 1; } } void init() { memset(a, 0, sizeof (a)); } Matrix operator * (const Matrix & ot) const { Matrix ret; ret.r = r, ret.c = ot.c; ret.init(); for (int i = 0; i < ret.r; ++i) { for (int j = 0; j < ret.c; ++j) { for (int k = 0; k < c; ++k) { ret.a[i][j] += a[i][k] * ot.a[k][j]; ret.a[i][j] %= m; } } } return ret; } void show() { puts(""); for (int i = 0; i < r; ++i) { for (int j = 0; j < c; ++j) { printf("%I64d ", a[i][j]); } puts(""); } puts(""); } }; Matrix _pow(Matrix a, LL b) { Matrix ret; ret.r = ret.c = 2; ret.unit(); while (b) { if (b & 1) { ret = ret * a; } b >>= 1; a = a * a; } return ret; } int main() { while (scanf("%I64d %I64d %I64d %I64d", &a, &b, &n, &m) != EOF) { Matrix A, B; A.init(); A.r = 2, A.c = 1; A.a[0][0] = (2*a*a+2*b) % m, A.a[1][0] = (2*a) % m; if (n == 1) { printf("%I64d\n", A.a[1][0]); continue; } else if (n == 2) { printf("%I64d\n", A.a[0][0]); continue; } B.r = B.c = 2; B.a[0][0] = (2*a)%m, B.a[0][1] = (((b-a*a)%m)+m)%m; B.a[1][0] = 1, B.a[1][1] = 0; A = _pow(B, n-2) * A; printf("%I64d\n", A.a[0][0]); } return 0; }