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;
}
原文地址:https://www.cnblogs.com/shuitiangong/p/12860260.html