HDU 5015 矩阵快速幂

来源:互联网 发布:h3c stp 阻塞端口 编辑:程序博客网 时间:2024/06/02 01:38

题意:给出矩阵的第0行(233,2333,23333,...)和第0列a1,a2,...an(n<=10,m<=10^9),给出式子: A[i][j] = A[i-1][j] + A[i][j-1],要求A[n][m]。

解法:看到n<=10和m<=10^9 应该对矩阵有些想法,现在我们假设要求A[a][b],则A[a][b] = A[a][b-1] + A[a-1][b] = A[a][b-1] + A[a-1][b-1] + A[a-2][b] = ...

这样相当于右图:,红色部分为绿色部分之和,而顶上的绿色部分很好求,左边的绿色部分(最多10个)其实就是:A[1][m-1],A[2][m-1]..A[n][m-1],即对每个1<=i<=n, A[i][m]都可由A[1][m-1],A[2][m-1]..A[n][m-1],于是建立12*12的矩阵:

,将中间矩阵求m-1次幂,与右边[A[0][1],A[1][1]..A[n][1],3]^T相乘,结果就可以得出了。

题解是转的别人的:http://www.cnblogs.com/whatbeg/p/3971994.html

#include <bits/stdc++.h>using namespace std;const int MOD = 1e7 + 7;struct Matrix{int mat[15][15];int n;void init(int nn){n = nn;memset(mat, 0, sizeof(mat));}Matrix operator*(const Matrix &b) const{Matrix ret; ret.init(n);for (int i = 0; i < n; i++)for (int j = 0; j < n; j++){ret.mat[i][j] = 0;for (int k = 0; k < n; k++){ret.mat[i][j] += (long long)mat[i][k] * b.mat[k][j] % MOD;if (ret.mat[i][j] >= MOD)ret.mat[i][j] -= MOD;}}return ret;}Matrix operator^(long long nn){Matrix tmp = *this, ret; ret.init(this->n);for (int i = 0; i < this->n; i++)ret.mat[i][i] = 1;while (nn){if (nn & 1)ret = ret * tmp;tmp = tmp * tmp;nn >>= 1;}return *this = ret;}void print(){for (int i = 0; i < n; i++)for (int j = 0; j < n; j++){cout << mat[i][j] << (j == n - 1 ? "\n" : " ");}}};int inp[20], n, m;Matrix A;int main(int argc, char const *argv[]){ios::sync_with_stdio(false);while (cin >> n >> m){for (int i = 0; i < n; i++){cin >> inp[i];inp[i] %= MOD;}A.init(n + 2);for (int j = 0; j < n; A.mat[n][j] = 1, j++)for (int i = 0; i <= j; i++)A.mat[i][j] = 1;A.mat[n][n] = 10; A.mat[n + 1][n] = 3; A.mat[n + 1][n + 1] = 1;//A.print();A^m;//A.print();long long ans = 0;for (int i = 0; i < n; i++){ans += (long long)inp[i] * A.mat[i][n - 1] % MOD;ans % MOD;}ans += (long long)233 * A.mat[n][n - 1];ans %= MOD;ans += (long long)A.mat[n + 1][n - 1];ans %= MOD;cout << ans << endl;}return 0;}


0 0
原创粉丝点击