HDU 5950 Recursive sequence 矩阵快速幂 思维
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5950
题目描述: 给你f(1), f(2), f(n) = f(n-1) + 2*f(n-2) + n^4, 输入n, f(1), f(2), 求出f(n)
解题思路:由于知道递推式, 很明显的矩阵快速幂, 图中就是求得的矩阵
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <string> #include <vector> #include <cstring> #include <iterator> #include <cmath> #include <algorithm> #include <stack> #include <deque> #include <map> #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 #define mem0(a) memset(a,0,sizeof(a)) #define meminf(a) memset(a,-0x3f,sizeof(a)) #define fi(n) for(i=0;i<n;i++) #define fj(m) for(j=0;j<m;j++) #define sca(x) scanf("%d",&x) #define ssca(x) scanf("%s",x) #define scalld(x) scanf("%I64d",&x) #define print(x) printf("%d\n", x) #define printlld(x) printf("%I64d\n",x) #define de printf("=======\n") #define yes printf("YES\n") #define no printf("NO\n") typedef long long ll; using namespace std; const ll mod = 2147493647; const int maxn = 7; const int temp = 7; typedef struct { ll mat[maxn][maxn]; void init() { mem0(mat); for( int i = 0; i < temp; i++ ) { for( int j = 0; j < temp; j++ ) { if( i == j ) mat[i][j] = 1; } } } } Matrix; Matrix matrix = {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 }; Matrix mul( Matrix m1, Matrix m2 ) { Matrix ret; mem0(ret.mat); for( int i = 0; i < temp; i++ ) { for( int j = 0; j < temp; j++ ) { for( int k = 0; k < temp; k++ ) { ret.mat[i][j] += m1.mat[i][k]*m2.mat[k][j] % mod; ret.mat[i][j] %= mod; // cout << ret.mat[i][j] << endl; } } } return ret; } Matrix matrix_quick_power( Matrix m, int times ) { Matrix ret; ret.init(); while( times ) { if( times & 1 ) ret = mul( ret, m ); times >>= 1; m = mul(m, m); } return ret; } void debug(Matrix m) { for( int i = 0; i < 7; i++ ) { for( int j = 0; j < 7; j++ ) { cout << m.mat[i][j] << " "; } cout << endl; } de; } int main() { // debug(matrix); // debug(matrix_quick_power( matrix, 1)); int t; sca(t); while( t-- ) { int n, a, b; scanf( "%d%d%d", &n, &a, &b ); if( n == 1 ) { printf( "%d\n", a ); continue; } if( n == 2 ) { printf( "%d\n", b ); continue; } Matrix initial; // for( int i = 0; i < temp; i++ ) { // for( int j = 0; j < temp; j++ ) { // initial.mat[i][j] = 1; // } // } mem0(initial.mat); // initial.init(); initial.mat[0][0] = b; initial.mat[0][1] = a; initial.mat[0][2] = 16; initial.mat[0][3] = 8; initial.mat[0][4] = 4; initial.mat[0][5] = 2; initial.mat[0][6] = 1; Matrix res = matrix_quick_power(matrix, n-2); // debug(res); // debug(initial); res = mul( initial, res ); // 当初写反了.....大坑啊TAT printf( "%lld\n", res.mat[0][0] ); } return 0; }
思考: 这道题虽然不难, 但是需要注意的细节很多, 比如说矩阵的乘法需要注意顺序, 还有有的时候矩阵需要初始化为单位矩阵, 但是有的时候由于需要会初始化为0矩阵, 还有最重要的一点, 我又一次见识到了, 如果进行运算的话, 一定, 一定要使运算的变量类型全部相同!如果有一个long long 就全部改成long long , 占不了多少存储空间的! 不然的话结果可能为0, 我先去试试!我的g++编译器是没有问题的, 可以进行正常运算, 但是评测机就不一样了,评测机int / ll 会变成0或者随机值吧, 所以坚决用同一类型! 以前我也碰到过这种情况, 我记得是int * int溢出之后g++是变成随机值的, 而编译器却直接变成0, 最后造成了RE(除0), 这就很尴尬
posted on 2017-08-23 22:57 FriskyPuppy 阅读(151) 评论(0) 编辑 收藏 举报