hdu 4549 M斐波那契数列

来源:互联网 发布:doge 动态软件 编辑:程序博客网 时间:2024/06/05 06:06

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

题目连接。。。

其中做了点优化,用该矩阵可由 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;}