hdu 4549 M斐波那契数列

矩阵乘法的快速幂和乘法的快速幂

题目连接。。。

其中做了点优化,用该矩阵可由 f0,f1 --> f2,f3 减少计算次数,如果数据量再大点应该看得出来效果

最关键的是在矩阵乘法中的取模运算要选 MOD-1,在这被坑的很惨

#include<stdio.h>
#include <string.h>
typedef __int64 ll;
const ll MOD = 1000000007;
struct matrix
{
    ll f11, f12, f21, f22;
    matrix() {f11 = f12 = f21 = 1; f22 = 2; }
    matrix operator *(matrix &a) const
    {
        matrix tp;
        tp.f11 = a.f11*f11 + a.f12*f21;
        tp.f11 %= MOD-1;
        tp.f12 = a.f11*f12 + a.f12*f22;
        tp.f12 %= MOD-1;
        tp.f21 = a.f21*f11+a.f22*f21;
        tp.f21 %= MOD-1;
        tp.f22 = a.f21*f12+a.f22*f22;
        tp.f22 %= MOD-1;
        return tp;
    }
};
ll getres(ll nm, ll c)
{
    ll res = 1, tp = nm;
    while (c)
    {
        if (c & 0x1) res *= tp;
        res %= MOD;
        tp *= tp;
        tp %= MOD;
        c>>= 1;
    }
    return res;
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
    int n;
    ll a, b;
    while (scanf("%I64d%I64d%d", &a, &b, &n) != EOF)
    {
        if (!n) printf("%I64d\n", a);
        else if ( n == 1) printf("%I64d\n", b);
        else if (!a || !b) printf("0\n");
        else
        {
            matrix res, tp ,c;
            int tm = n/2-1;
            ll cot = 1;
            while (tm)
            {
                if (tm & 0x1) res = res*tp;
                tp = tp*tp;
                tm >>= 1;
            }
            // a
            ll a1 = res.f11, a2 = res.f21;
            // b
            ll b1 = res.f12, b2 = res.f22;
            if ( n & 0x1) 
            {
                cot = getres(a, a2)*getres(b, b2);
                cot %= MOD;
            }
            else
            {
                cot = getres(a, a1)*getres(b, b1);
                cot %= MOD;
            }
            printf("%I64d\n", cot);
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值