您的位置:首页 > 产品设计 > UI/UE

[hdu 5950 Recursive sequence] 矩阵快速幂

2016-10-31 01:34 489 查看

[hdu 5950 Recursive sequence] 矩阵快速幂

题目链接[hdu 5950 Recursive sequence]

题意描述:已知通项公式Fi=Fi−1+2∗Fi−2+i4, 并且已知F1=a,F2=b和一个数字n,求Fn%2147493647。(1≤n,a,b<231)

解题思路

显然的矩阵快速幂。

需要维护的值有Fi−1,Fi−2,n4,n3,n2,n,1这七个变量。维护红色变量的原因是方便求出(n+1)4。

然后构造矩阵就可以了。

#include <bits/stdc++.h>
using namespace std;

typedef __int64 LL;
const LL MOD = 2147493647;

LL T, N, A, B;

struct Mat {
static const int MSZ = 7;
LL m[MSZ][MSZ];
void O() { memset(m, 0, sizeof(m)); }
void E() {
O();
for(int i = 0; i < MSZ; i++) m[i][i] = 1;
}
void assign(LL ar[MSZ][MSZ]) {
for(int i = 0; i < MSZ; i++) {
for(int j = 0; j < MSZ; j++) {
m[i][j] = ar[i][j];
}
}
}
Mat operator * (const Mat& e) const {
Mat ret; ret.O();
for(int k = 0; k < MSZ; k++) {
for(int i = 0; i < MSZ; i++) {
if(m[i][k] == 0) continue;
for(int j = 0; j < MSZ; j++) {
ret.m[i][j] += m[i][k] * e.m[k][j] % MOD;
ret.m[i][j] %= MOD;
}
}
}
return ret;
}
Mat operator ^ (LL b) const {
Mat ret, a(*this); ret.E();
while(b > 0) {
if(b & 1) ret = ret * a;
a = a * a;
b >>= 1;
}
return ret;
}
} tras, init, res;

int main() {
//    freopen("input.txt", "r", stdin);
// 变换矩阵
LL x[][Mat::MSZ] = {
{1, 2, 1, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 4, 6, 4, 1},
{0, 0, 0, 1, 3, 3, 1},
{0, 0, 0, 0, 1, 2, 1},
{0, 0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 0, 1}
};
tras.assign(x);
cin >> T;
while(T --) {
cin >> N >> A >> B;
if(N == 1) {
cout << A % MOD << "\n";
continue;
}
if(N == 2) {
cout << B % MOD << "\n";
continue;
}
// 初始矩阵
LL y[][Mat::MSZ] = {
{B, 0, 0, 0, 0, 0, 0},
{A, 0, 0, 0, 0, 0, 0},
{81, 0, 0, 0, 0, 0, 0},
{27, 0, 0, 0, 0, 0, 0},
{9, 0, 0, 0, 0, 0, 0},
{3, 0, 0, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 0, 0}
};
init.assign(y);
res = tras ^ (N - 2);
res = res * init;
cout << res.m[0][0] << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: