【hdu1005】矩阵快速乘法,递归二分形式

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1005

/*

题目:

f(n)       = a * f(n - 1)  + b * f(n - 2)

给a和b,求fn,n <= 10^9

思路:

把f(n)迭代公式写成矩阵乘法的形式

 

 f(n)        = a * f(n - 1)  + b * f(n - 2)

  f(n- 1)    = 1 * f(n - 1)  + 0 * f(n - 2)

  可得

 [f(n) f(n - 1)]'    = [a b; 1 0] *[f(n - 1) f(n - 2)]'

                    = [a b; 1 0]^(n - 2) *[f(2) f(1)]'

  计算

  [ab; 1 0]^(n - 2),用二分法

 

矩阵快速乘法

 

时间复杂度分析:n = 10^9,那么只可能是O(1), O(logn)

*/

#include<stdio.h>

void matrixMul(int m1[][2], int m2[][2], int m12[][2]) {
    int n = 2;
    int i, j, k;
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            int sum = 0;
            for (k = 0; k < n; k++) {
                sum = (sum + m1[i][k] * m2[k][j]) % 7;
            }
            m12[i][j] = sum;
        }
    }
}

void matrixPower(int m1[][2], int n, int m2[][2]) {
    if (n == 1) {
        m2[0][0] = m1[0][0];
        m2[0][1] = m1[0][1];
        m2[1][0] = m1[1][0];
        m2[1][1] = m1[1][1];
        return;
    }
    
    int m3[2][2];
    int m4[2][2];
    if (n % 2 == 0) {
        matrixPower(m1, n / 2, m3);
        matrixMul(m3, m3, m2);
    } else {
        matrixPower(m1, n / 2, m3);
        matrixMul(m3, m3, m4);
        // printf("~m4~ %d %d %d %d\n", m4[0][0], m4[0][1], m4[1][0], m4[1][1]);
        matrixMul(m4, m1, m2);
    }
}

void solve(int a, int b, int n) {
    if (n <= 2){
        printf("1\n");
        return;
    }

    int m1[2][2], m2[2][2];
    m1[0][0] = a;
    m1[0][1] = b;
    m1[1][0] = 1;
    m1[1][1] = 0;
    //matrixMul(m1, m1, m2);
    //printf("%d %d %d %d\n", m2[0][0], m2[0][1], m2[1][0], m2[1][1]);
    matrixPower(m1, n - 2, m2);
    int fn = (m2[0][0] + m2[0][1]) % 7;
    printf("%d\n", fn);
}

int main() {
    int a, b, n;
    while (scanf("%d %d %d", &a, &b, &n) && !(a==0)) {
    //    for (int i = 1; i <= n; i++) {
    //        solve(a, b, i);
    //    }
        solve(a, b, n);
    }
    return 0;
}


你可能感兴趣的:(【hdu1005】矩阵快速乘法,递归二分形式)