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)

  解题思路:由于知道递推式, 很明显的矩阵快速幂, 图中就是求得的矩阵

                                  

  代码: 

#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
", x)
#define printlld(x) printf("%I64d
",x)
#define de printf("=======
")
#define yes printf("YES
")
#define no printf("NO
")
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
", a );
            continue;
        }
        if( n == 2 ) {
            printf( "%d
", 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
", res.mat[0][0] );
    }
    return 0;
}
View Code

  思考: 这道题虽然不难, 但是需要注意的细节很多, 比如说矩阵的乘法需要注意顺序, 还有有的时候矩阵需要初始化为单位矩阵, 但是有的时候由于需要会初始化为0矩阵, 还有最重要的一点, 我又一次见识到了, 如果进行运算的话, 一定, 一定要使运算的变量类型全部相同!如果有一个long long 就全部改成long long , 占不了多少存储空间的! 不然的话结果可能为0, 我先去试试!我的g++编译器是没有问题的, 可以进行正常运算, 但是评测机就不一样了,评测机int / ll 会变成0或者随机值吧,  所以坚决用同一类型! 以前我也碰到过这种情况, 我记得是int * int溢出之后g++是变成随机值的, 而编译器却直接变成0, 最后造成了RE(除0), 这就很尴尬

原文地址:https://www.cnblogs.com/FriskyPuppy/p/7420696.html