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

ICPC 沈阳站C题 HDU 5950 Recursive sequence 矩阵快速幂 线性递推

2016-11-04 17:41 591 查看
http://acm.hdu.edu.cn/showproblem.php?pid=5950

给出前两项a,b,关系式 f[i] = f[i-1] + f[i-2] * 2 + i^4,问第n项是多少(对2147493647取模), n,a,b < 2^31

矩阵,维护f[i], f[i-1], i^4, i^3,i^2,i还有一个常数1,得到七维矩阵,以为开始有两项,i = 2,所以也得到初始的1*7矩阵



//
//  main.cpp
//  5950 Recursive sequence 矩阵快速幂 线性递推
//
//  Created by czf on 2016/11/3.
//  Copyright © 2016年 czf. All rights reserved.
//

#include <cstdio>
#include <cstring>
typedef long long LL;

const int SIZE = 7;
const LL MOD = 2147493647;

struct Mat {
LL a[SIZE][SIZE];
void setOne() {
memset(a, 0, sizeof(a));
for (int i = 0; i < SIZE; i ++) a[i][i] = 1;
}
void setZero() {
memset(a, 0, sizeof(a));
}
void print() {
for (int i = 0; i < SIZE; i ++) {
for (int j = 0; j < SIZE; j ++) {
printf("%lld%c",a[i][j],j == SIZE-1 ? '\n' : ' ');
}
}
printf("\n");
}
Mat operator * (const Mat &rhs) const {
Mat ret; ret.setZero();
for (int i = 0; i < SIZE; i ++) {
for (int j = 0; j < SIZE; j ++) {
for (int k = 0; k < SIZE; k ++) {
ret.a[i][j] = (ret.a[i][j] + (a[i][k] % MOD) * (rhs.a[k][j] % MOD) % MOD) % MOD;
}
}
}
return ret;
}
Mat operator ^ (LL n) const {
Mat base = (*this), ret; ret.setOne();
while (n) {
if (n & 1) ret = ret * base;
base = base * base;
n >>= 1;
}
return ret;
}
};

int main() {
int T; scanf("%d",&T);
while (T--) {
LL n, a, b; scanf("%lld%lld%lld",&n,&a,&b);
if (n <= 2) {
printf("%lld\n",n == 1 ? a : b);
}
Mat m1 = {
b, a, 16, 8, 4, 2, 1,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0
};
Mat m2 = {
1, 1, 0, 0, 0, 0, 0,
2, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 0,
4, 0, 4, 1, 0, 0, 0,
6, 0, 6, 3, 1, 0, 0,
4, 0, 4, 3, 2, 1, 0,
1, 0, 1, 1, 1, 1, 1
};
m2 = m2 ^ (n-2);
m1 = m1 * m2;
printf("%lld\n",m1.a[0][0]);
}
return 0;
}


哎,一开始写矩阵乘法累加变赋值了...半天没发现

231
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  矩阵快速幂