• hdu 4291矩阵快速幂


    这题是去年成都网络赛的题,当时没做出来,杯具呀。

    其实最关键的就是要懂得取余一定会循环的,如果能够找出循环节,就是一个巨大的突破。然后就是g(n)的求法,很显然硬求是不可能的,我们去年做这题的时候试图去找g(n)的通项公式,都找得差不多了,但实际上那毫无意义。因为我们是要找循环节,所以应该一层层地找。先看g(n) % 1000000007到哪里会循环。可以用矩阵的方法求g(n),暴力打出来,发现循环节是222222224。再来看g(g(n)) % 1000000007到哪里会循环。因为g(g(n)) % 1000000007对g(n)每隔222222224结果就会循环一次,所以g(g(n)) % 1000000007 = g(g(n) % 222222224) % 1000000007。所以g(n) % 222222224的循环节也就是g(g(n)) % 1000000007的循环节。暴力求出来是183120。最后再看g(g(g(n))) % 1000000007的循环节。同理g(n) % 183120的循环节就是g(g(g(n))) % 1000000007的循环节。暴力求出来是240。也就是说,最后的结果,n每隔240就会循环。所以最后的结果就是g(g(g(n % 240) % 183120) % 222222224) % 1000000007。用矩阵快速幂就可以过了。

    我的暴力求循环节的代码如下:

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <set>
    #include <map>
    #include <stack>
    #include <string>
    #include <vector>
    #include <deque>
    #include <list>
    #include <functional>
    #include <numeric>
    #include <cctype>
    using namespace std;
    const int MAX_ORDER = 2;
    const int MOD = 1000000007;
    typedef long long typec;
    typedef struct MyMatrix {
        int row, col;
        typec num[MAX_ORDER][MAX_ORDER];
        MyMatrix(int rr, int cc) {
            row = rr;
            col = cc;
        }
        inline void init() {
            memset(num, 0, sizeof(num));
        }
    } MyMatrix;
    //矩阵乘法。注意:ma.col与mb.row一定要相等,否则会出问题
    MyMatrix operator*(MyMatrix ma, MyMatrix mb) {
        int row = ma.row;
        int col = mb.col;
        int K = ma.col;
        MyMatrix numc(row, col);
        numc.init();
        int i, j, k;
        for (i = 0; i < row; i++) {
            for (j = 0; j < col; j++) {
                for (k = 0; k < K; k++) {
                    numc.num[i][j] += ma.num[i][k] * mb.num[k][j];
                    numc.num[i][j] %= MOD;
                }
            }
        }
        return numc;
    }
    //矩阵快速幂。注意:ma.col与ma.row一定要相等,否则会出问题
    MyMatrix mpow(MyMatrix ma, int x) {
        int ord = ma.row;
        MyMatrix numc(ord, ord);
        numc.init();
        for (int i = 0; i < ord; i++) {
            numc.num[i][i] = 1;
        }
        for (; x; x >>= 1) {
            if (x & 1) {
                numc = numc * ma;
            }
            ma = ma * ma;
        }
        return numc;
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("data.in", "r", stdin);
    #endif
        MyMatrix ori(1, 2);
        ori.num[0][0] = 0;
        ori.num[0][1] = 1;
        MyMatrix tran(2, 2);
        tran.num[0][0] = 0;
        tran.num[0][1] = 1;
        tran.num[1][0] = 1;
        tran.num[1][1] = 3;
        for(int t = 1; ; t++) {
            ori = ori * tran;
            if(ori.num[0][0] == 0 && ori.num[0][1] == 1) {
                printf("%d\n", t);
                break;
            }
        }
        return 0;
    }

    最后通过的代码如下:

    /*
     * hdu4291/win.cpp
     * Created on: 2012-11-4
     * Author    : ben
     */
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <set>
    #include <map>
    #include <stack>
    #include <string>
    #include <vector>
    #include <deque>
    #include <list>
    #include <functional>
    #include <numeric>
    #include <cctype>
    using namespace std;
    const int MAX_ORDER = 2;
    int MOD;
    typedef long long typec;
    typedef struct MyMatrix {
        int row, col;
        typec num[MAX_ORDER][MAX_ORDER];
        MyMatrix(int rr, int cc) {
            row = rr;
            col = cc;
        }
        inline void init() {
            memset(num, 0, sizeof(num));
        }
    } MyMatrix;
    //矩阵乘法。注意:ma.col与mb.row一定要相等,否则会出问题
    MyMatrix operator*(MyMatrix ma, MyMatrix mb) {
        int row = ma.row;
        int col = mb.col;
        int K = ma.col;
        MyMatrix numc(row, col);
        numc.init();
        int i, j, k;
        for (i = 0; i < row; i++) {
            for (j = 0; j < col; j++) {
                for (k = 0; k < K; k++) {
                    numc.num[i][j] += ma.num[i][k] * mb.num[k][j];
                    numc.num[i][j] %= MOD;
                }
            }
        }
        return numc;
    }
    //矩阵快速幂。注意:ma.col与ma.row一定要相等,否则会出问题
    MyMatrix mpow(MyMatrix ma, int x) {
        int ord = ma.row;
        MyMatrix numc(ord, ord);
        numc.init();
        for (int i = 0; i < ord; i++) {
            numc.num[i][i] = 1;
        }
        for (; x; x >>= 1) {
            if (x & 1) {
                numc = numc * ma;
            }
            ma = ma * ma;
        }
        return numc;
    }
    
    inline MyMatrix getori() {
        MyMatrix ori(1, 2);
        ori.num[0][0] = 0;
        ori.num[0][1] = 1;
        return ori;
    }
    
    inline MyMatrix gettran() {
        MyMatrix tran(2, 2);
        tran.num[0][0] = 0;
        tran.num[0][1] = 1;
        tran.num[1][0] = 1;
        tran.num[1][1] = 3;
        return tran;
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("data.in", "r", stdin);
    #endif
        long long temp;
        while(scanf("%I64d", &temp) == 1) {
            int n = (int)(temp % 240);
            MOD = 183120;
            n = (getori() * mpow(gettran(), n)).num[0][0];
            MOD = 222222224;
            n = (getori() * mpow(gettran(), n)).num[0][0];
            MOD = 1000000007;
            n = (getori() * mpow(gettran(), n)).num[0][0];
            printf("%d\n", n);
        }
        return 0;
    }
  • 相关阅读:
    git常用命令
    Laravel框架数据库CURD操作、连贯操作总结
    Laravel 5 系列入门教程(四)【最适合中国人的 Laravel 教程】【完结】
    Laravel 5 系列入门教程(三)【最适合中国人的 Laravel 教程】
    Laravel 5 系列入门教程(二)【最适合中国人的 Laravel 教程】
    Laravel 5 系列入门教程(一)【最适合中国人的 Laravel 教程】
    linux环境下安装nginx步骤
    关于C++中的虚拟继承的一些总结
    C++中拷贝构造函数
    C++之类与对象(3)
  • 原文地址:https://www.cnblogs.com/moonbay/p/2753465.html
Copyright © 2020-2023  润新知