其他分享
首页 > 其他分享> > HDU 4549 M斐波那契数列(矩阵快速幂,欧拉降幂)

HDU 4549 M斐波那契数列(矩阵快速幂,欧拉降幂)

作者:互联网

题目链接

解题思路

  很容易推导出f(n)的值是a的幂与b的幂的乘积,并且它们的指数与斐波那契数列有关。但是,首先第一个问题是它们的指数太大,如果暴力求的话一定会超时所以第一步需要用矩阵快速幂求出它们的指数。其次,得到的指数很大,算特别大的指数的时候,肯定是需要欧拉降幂的,因为题中的a和b都小于1e9+7,所以直接对指数模(mod-1)即可,最后用快速幂算出结果就行了。

代码

ll ans[2][2], res[2][2], tmp[2][2];
void mul(ll a[][2], ll b[][2]) {
    zero(tmp);
    for (int i = 0; i<2; ++i)
        for (int j = 0; j<2; ++j)
            for (int k = 0; k<2; ++k)
                tmp[i][j] = (tmp[i][j]+a[i][k]*b[k][j]%(MOD-1))%(MOD-1);
    for (int i = 0; i<2; ++i)
        for (int j = 0; j<2; ++j)
            a[i][j] = tmp[i][j];
}
void mxqp(ll y) {
    ans[0][0] = ans[1][1] = 1; ans[0][1] = ans[1][0] = 0;
    res[0][0] = res[0][1] = res[1][0] = 1; res[1][1] = 0;
    while(y) {
        if (y&1) mul(ans, res);
        mul(res, res);
        y >>= 1;
    }
}
ll qp(ll x, ll y) {
    ll res = x, ans = 1;
    while(y) {
        if (y&1) ans = ans*res%MOD;
        res = res*res%MOD;
        y >>= 1;
    }
    return ans;
}
int main(){
    ll a, b, n;
    while(cin>>a>>b>>n) {
        if (n==0) cout << a << endl;
        else if (n==1) cout << b << endl;
        else {
            mxqp(n-1);
            //cout << ans[0][0] << ' ' << ans[0][1] << endl;
            cout <<  qp(b,ans[0][0])*qp(a, ans[0][1])%MOD << endl;
        } 
    }
    return 0;
}

标签:tmp,HDU,降幂,res,ll,指数,斐波,ans,MOD
来源: https://www.cnblogs.com/shuitiangong/p/12860260.html