HDU 5950 Recursive sequence(矩陣構造+矩陣快速冪)
阿新 • • 發佈:2019-02-18
題目地址
題意:就說告訴你f(1) = a,f(2) = b,f(n) = f(n−1)+2∗f(n−2)+n^4,求出f(n)的值。
思路:這類題目就是用矩陣快速冪來寫的,這類題目難的就是構造矩陣,我們可以發現一些規律(如下)
f(n) = f(n−1)+2∗f(n−2)+n^4
(n+1)^4=n^4+4*n^3+6*n^2+4*n+1
(n+1)^3=n^3+3*n^2+3*n+1
(n+1)^2=n^2+2*n+1
n+1=n+1
1=1
然後我們就可以構造出一個矩陣為:然後就用矩陣快速冪就好了。
#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <cstdio>
#include <algorithm>
#define LL long long
#define N 1100
#define M 50010
#define inf 0x3f3f3f3f
using namespace std;
const LL mod = 2147493647;
const double eps = 1e-9;
struct node {
int n, m;
LL jz[7][7];
}sum, a;
node mul(node x, node y) {
node num;
num.n = x.n;
num.m = y.m;
for (int i = 0; i < x.n; i++) {
for (int j = 0; j < y.m; j++) {
num.jz [i][j] = 0;
for (int k = 0; k < x.m; k++) {
num.jz[i][j] += x.jz[i][k] * y.jz[k][j];
num.jz[i][j] %= mod;
}
}
}
return num;
}
node pow(node x, node y, LL m) {
while (m) {
if (m & 1) {
x = mul(x, y);
}
m /= 2;
y = mul(y, y);
}
return x;
}
void init(int aa, int bb) {
a.n = 7;
a.m = 7;
a.jz[0][0] = 1, a.jz[0][1] = 1, a.jz[0][2] = 0, a.jz[0][3] = 0, a.jz[0][4] = 0, a.jz[0][5] = 0, a.jz[0][6] = 0;
a.jz[1][0] = 2, a.jz[1][1] = 0, a.jz[1][2] = 0, a.jz[1][3] = 0, a.jz[1][4] = 0, a.jz[1][5] = 0, a.jz[1][6] = 0;
a.jz[2][0] = 1, a.jz[2][1] = 0, a.jz[2][2] = 1, a.jz[2][3] = 0, a.jz[2][4] = 0, a.jz[2][5] = 0, a.jz[2][6] = 0;
a.jz[3][0] = 4, a.jz[3][1] = 0, a.jz[3][2] = 4, a.jz[3][3] = 1, a.jz[3][4] = 0, a.jz[3][5] = 0, a.jz[3][6] = 0;
a.jz[4][0] = 6, a.jz[4][1] = 0, a.jz[4][2] = 6, a.jz[4][3] = 3, a.jz[4][4] = 1, a.jz[4][5] = 0, a.jz[4][6] = 0;
a.jz[5][0] = 4, a.jz[5][1] = 0, a.jz[5][2] = 4, a.jz[5][3] = 3, a.jz[5][4] = 2, a.jz[5][5] = 1, a.jz[5][6] = 0;
a.jz[6][0] = 1, a.jz[6][1] = 0, a.jz[6][2] = 1, a.jz[6][3] = 1, a.jz[6][4] = 1, a.jz[6][5] = 1, a.jz[6][6] = 1;
sum.n = 1;
sum.m = 7;
sum.jz[0][0] = bb;
sum.jz[0][1] = aa;
sum.jz[0][2] = 16;
sum.jz[0][3] = 8;
sum.jz[0][4] = 4;
sum.jz[0][5] = 2;
sum.jz[0][6] = 1;
}
int main() {
cin.sync_with_stdio(false);
int T;
LL aa, bb, n;
cin >> T;
while (T--) {
cin >> n >> aa >> bb;
if (n == 1) {
cout << aa << endl;
continue;
}
if (n == 2) {
cout << bb << endl;
continue;
}
init(aa, bb);
sum = pow(sum, a, n - 2);
cout << sum.jz[0][0] << endl;
}
return 0;
}