http://acm.hdu.edu.cn/showproblem.php?pid=5950
一开始以为i^4不能矩阵快速幂,但是结论是可以得,那么要怎么递推呢?
矩阵快速幂的思路都是一样的,matrix_a * matrix_b ^ n
其中,想要维护什么,就在matrix_a写,比如现在是F[n - 1], F[n - 2],我想要递推到下一项,那么就
会变成F[n], F[n - 1],这个时候,你就要寻找一下F[n]和F[n - 1]有什么关系。
i^4也一样,想要从i^4 递推到 (i + 1)^4,就要看看他们之间有什么关系。
那么把(i + 1)^4用二项式定理展开,就知道了。
关键要掌握矩阵快速幂的思路,都是从F[n]递推到F[n + 1],寻找一下它们之间的关系就好
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
const LL MOD = 2147493647;
const int maxn = 8 + 2;
struct Matrix {
LL a[maxn][maxn];
int row, col;
};
struct Matrix matrix_mul(struct Matrix a, struct Matrix b, LL MOD) {
struct Matrix c = {0};
c.row = a.row;
c.col = b.col;
for (int i = 1; i <= a.row; ++i) {
for (int k = 1; k <= a.col; ++k) {
if (a.a[i][k]) {
for (int j = 1; j <= b.col; ++j) {
c.a[i][j] += a.a[i][k] * b.a[k][j];
c.a[i][j] = (c.a[i][j] + MOD) % MOD;
}
}
}
}
return c;
}
struct Matrix quick_matrix_pow(struct Matrix ans, struct Matrix base, int n, LL MOD) {
while (n) {
if (n & 1) {
ans = matrix_mul(ans, base, MOD);
}
n >>= 1;
base = matrix_mul(base, base, MOD);
}
return ans;
}
void work() {
int n, a, b;
scanf("%d%d%d", &n, &a, &b);
if (n == 1) {
printf("%d\n", a);
return;
}
if (n == 2) {
printf("%d\n", b);
return;
}
struct Matrix t1 = {0};
t1.row = 1, t1.col = 7;
t1.a[1][1] = b, t1.a[1][2] = a, t1.a[1][3] = 81, t1.a[1][4] = 27, t1.a[1][5] = 9, t1.a[1][6] = 3, t1.a[1][7] = 1;
struct Matrix t2 = {0};
t2.row = t2.col = 7;
t2.a[1][1] = 1, t2.a[1][2] = 1;
t2.a[2][1] = 2;
t2.a[3][1] = 1, t2.a[3][3] = 1;
t2.a[4][3] = 4, t2.a[4][4] = 1;
t2.a[5][3] = 6, t2.a[5][4] = 3, t2.a[5][5] = 1;
t2.a[6][3] = 4, t2.a[6][4] = 3, t2.a[6][5] = 2, t2.a[6][6] = 1;
t2.a[7][3] = 1, t2.a[7][4] = 1, t2.a[7][5] = 1, t2.a[7][6] = 1, t2.a[7][7] = 1;
struct Matrix ans = quick_matrix_pow(t1, t2, n - 2, MOD);
printf("%I64d\n", ans.a[1][1]);
}
int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
int t;
scanf("%d", &t);
while (t--) work();
return 0;
}
View Code