您的位置:首页 > 其它

POJ-3070-Fibonacci-求Fibonacci的矩阵方法,O(log(n))

2011-03-02 23:51 423 查看
平时一般求Fibonacci数列都是用递归求的,没想到还可以利用矩阵的幂求,算是长见识了。



为求A的n次幂,使用了分治法,复杂度为O(log(n))。

#include <iostream>
using namespace std;

/*2*2矩阵类*/
class Matrix {
public:
    /*构造函数*/
    Matrix(__int64 a00 = 0, __int64 a01 = 0, __int64 a10 = 0, __int64 a11 = 0) {
        this->a00 = a00;
        this->a01 = a01;
        this->a10 = a10;
        this->a11 = a11;
    }

    __int64 a00;
    __int64 a01;
    __int64 a10;
    __int64 a11;
};

Matrix multiply(const Matrix &a, const Matrix &b) {
    Matrix ans;
    /*根据题意要求,只需取最后四位数字即可,故取模10000*/
    ans.a00 = (a.a00 * b.a00 + a.a01 * b.a10) % 10000;
    ans.a01 = (a.a00 * b.a01 + a.a01 * b.a11) % 10000;
    ans.a10 = (a.a10 * b.a00 + a.a11 * b.a10) % 10000;
    ans.a11 = (a.a10 * b.a01 + a.a11 * b.a11) % 10000;

    return ans;
}

/*求2*2矩阵[1 1 1 0]的n(n >= 1)次幂。分治法求矩阵的幂A
。
 *先求A[n/2],当然要分n的奇偶进行对应处理。
 */
Matrix pow(int n) {
    Matrix ans;
    if(n == 1) {
        ans.a00 = 1; ans.a01 = 1; ans.a10 = 1; ans.a11 = 0;
    } else if(n % 2 == 0) {
        ans = pow(n / 2);
        ans = multiply(ans, ans);
    } else if(n % 2 == 1) {
        ans = pow((n - 1) / 2);
        ans = multiply(ans, ans);
        Matrix one(1, 1, 1, 0);
        ans = multiply(ans, one);
    }

    return ans;
}

__int64 fac(int n) {
    if(n == 0)
        return 0;
    if(n == 1)
        return 1;

    Matrix ans = pow(n - 1);
    return ans.a00; //矩阵第一行第一列元素即为fac

}

int main()
{
    int n;
    while(cin >> n, n != -1) {
        int output;
        output = fac(n) % 10000;
        cout << output << endl;
    }

    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: