zoukankan      html  css  js  c++  java
  • 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), 这就很尴尬

  • 相关阅读:
    枚举和字符串之间的转换 [转帖]
    escape,encodeURI,encodeURIComponent函数比较[转帖]
    .net中的Provider模式 [转帖]
    ogg转到mp3
    四季养生(樊正伦教授)
    JavaScript高阶之路
    Python初识
    理解error和exception之间的区别(转)
    一些有用的话
    《爱在雨季》片尾曲
  • 原文地址:https://www.cnblogs.com/FriskyPuppy/p/7420696.html
Copyright © 2011-2022 走看看