hdu 5015(矩阵快速幂)

题意:有一个矩阵横排第一行初始是0,233,2333,23333...,然后给出计算公式a[i][j] = a[i - 1][j] + a[i][j - 1],然后给出了n和m和第一列的各值要求计算a[n][m]的值。

题解:n <= 10但m <= 10^9,空间和时间花费都大,已知第一列a0,a1,a2......an,那么第二列每个数字就是b1 = a1 + 233,b2 = b1 + a2 = a1 + a2 + 233... 找到特点后构造矩阵然后用矩阵快速幂求解。

#include 
#include 
#define ll long long
const int N = 15;
const int MOD = 10000007;
int n, m;
struct Mat {
    ll a[N][N];
    Mat() {
        memset(a, 0, sizeof(a));
    }
    Mat operator * (Mat b) {
        Mat c;
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                for (int k = 0; k < n; k++)
                    c.a[i][j] = (c.a[i][j] + a[i][k] * b.a[k][j]) % MOD;
        return c;
    }
};

Mat f(Mat b, int m) {
    Mat c;
    for (int i = 0; i < n; i++)
        c.a[i][i] = 1;
    while (m) {
        if (m & 1)
            c = c * b;
        b = b * b;
        m >>= 1;
    }
    return c;
}

int main() {
    while (scanf("%d%d", &n, &m) == 2) {
        Mat A;
        A.a[0][0] = 1;
        A.a[1][0] = 1;
        A.a[1][1] = 10;
        n += 2;
        for (int i = 2; i < n; i++)
            for (int j = 1; j <= i; j++)
                A.a[i][j] = 1;
        A = f(A, m);
        ll temp[N], res = 0;
        temp[0] = 3;
        temp[1] = 233;
        for (int i = 2; i < n; i++)
            scanf("%lld", &temp[i]);
        for (int i = 0; i < n; i++)
            res = (res + temp[i] * A.a[n - 1][i] % MOD) % MOD;
        printf("%lld\n", res);
    }
    return 0;
}


你可能感兴趣的:(ACM-矩阵快速幂)