HDU-4291 A Short problem 嵌套循环节+矩阵快速幂

将gg(n)视为一个未知元,先由1000000007找出循环节222222224,然后再找出g(n)为变量时的循环节183120,然后应用矩阵快速幂求解即可。

代码如下:

#include<iostream>

#include<cstdio>

#include<cstdlib>

#include<algorithm>

#include<cmath>

#include<queue>

#include<set>

#include<map>

#include<cstring>

#include<vector>

#include<string>

using namespace std;



typedef long long Int64;



int MOD;



struct Matrix {

    Int64 a[2][2];

    inline Matrix () {

        memset(a, 0, sizeof (a));    

    }

    inline Matrix(int _a, int b, int c, int d) {

        a[0][0] = _a, a[0][1] = b;

        a[1][0] = c, a[1][1] = d;

    }

    inline Matrix operator * (Matrix y) {

        Matrix ret;

        for (int i = 0; i < 2; ++i) {

            for (int j = 0; j < 2; ++j) {

                for (int k = 0; k < 2; ++k) {

                    ret.a[i][j] += (a[i][k] * y.a[k][j]) % MOD;

                }

                ret.a[i][j] %= MOD;

            }    

        }

        return ret;

    }

    inline Matrix pow_mod(Int64 b, int mod) {

        Matrix ret(1, 0, 0, 1);

        MOD = mod;

        while (b) {

            if (b & 1) {

                ret = ret * *this;

            }

            *this = *this * *this;

            b >>= 1;

        }

        return ret;

    }

};



// 222222224 第一个循环节,表示g[222222224]%MOD = 0, g[222222225]%MOD = 1 

// 再将222222224作为MOD数,寻找下一个循环节 

// 下一个循环节是 183120,原因同上

// 找到循环节后就是矩阵快速幂了



inline Int64 solve(Int64 x, int mod) {

    if (x == 0) return 0;

    Matrix r(3, 1, 1, 0);

    return r.pow_mod(x-1, mod).a[0][0];

}



int main(  )

{

    Int64 N;

    while (scanf("%I64d", &N) == 1) {

        printf("%I64d\n", solve(solve(solve(N, 183120), 222222224), 1000000007));

    }

    return 0;

}

 

你可能感兴趣的:(HDU)