【hdu5015】233 Matrix——矩阵快速幂

来源:互联网 发布:怎么用u盘安装ubuntu 编辑:程序博客网 时间:2024/06/06 08:52

题目:

233 Matrix

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1588    Accepted Submission(s): 939


Problem Description
In our daily life we often use 233 to express our feelings. Actually, we may say 2333, 23333, or 233333 ... in the same meaning. And here is the question: Suppose we have a matrix called 233 matrix. In the first line, it would be 233, 2333, 23333... (it means a0,1 = 233,a0,2 = 2333,a0,3 = 23333...) Besides, in 233 matrix, we got ai,j = ai-1,j +ai,j-1( i,j ≠ 0). Now you have known a1,0,a2,0,...,an,0, could you tell me an,m in the 233 matrix?
 

Input
There are multiple test cases. Please process till EOF.

For each case, the first line contains two postive integers n,m(n ≤ 10,m ≤ 109). The second line contains n integers, a1,0,a2,0,...,an,0(0 ≤ ai,0 < 231).
 

Output
For each case, output an,m mod 10000007.
 

Sample Input
1 112 20 03 723 47 16
 

Sample Output
234279972937
Hint
 

Source
2014 ACM/ICPC Asia Regional Xi'an Online
 

Recommend
hujie   |   We have carefully selected several similar problems for you:  5634 5633 5632 5631 5630 
描述:给定233矩阵第0行是2333每次多一个3,给出矩阵元素的递推关系是一个广义的杨辉三角,给定第0列元素以及有n行m列,求a(n,m)

题解:一看到m特别大,就不要想用正常的杨辉三角去一步步推,一定是需要矩阵快速幂去加速运算过程,那么问题来了,这个矩阵如何来找到。首先可以看出,这个矩阵是可以按列进行转移的,第一行都可以看作是前一个*10+3,那么构造新的矩阵的第一列就全是10(转移矩阵左乘列矩阵),然后在列矩阵最后一位加上一个3,将第0列的0元素改为23,这样第一列也满足了这样的规律。接下来看最后一行,由于我们多了一个3,而每次转移都要保持它,所以转移矩阵的最后一列就都是1;然后再分析原矩阵的构造过程,可以看出从第一行开始,每个元素都等于它的前缀(前面所有元素)和,因此转移矩阵在第i行就有i个1.这样转移矩阵就构造结束了。

http://blog.csdn.net/rowanhaoa/article/details/39343769  这里有带图的解释,更直观一些。

代码:

#include <cstdio>#include <cstring>#include <iostream>using namespace std;struct matrix{__int64 mat[15][15];matrix(){memset(mat, 0, sizeof(mat));}};int n;const int mod = 10000007;matrix mul(matrix B, matrix A)         //左乘列矩阵{int i, j, k;matrix C;for (i = 1; i <= n + 2; i++)for (j = 1; j <= n + 2; j++)for (k = 1; k <= n + 2; k++)C.mat[i][j] = (C.mat[i][j]+B.mat[i][k] * A.mat[k][j])%mod;return C;}matrix powmul(matrix A, int m){matrix ans;for (int i = 1; i <= n + 2; i++)ans.mat[i][i] = 1;              //单位矩阵while (m > 0){if (m & 1)ans = mul(ans, A);A = mul(A, A);m >>= 1;}return ans;}int main(){//freopen("input.txt", "r", stdin);int m;while (scanf("%d%d",&n,&m) != EOF){matrix A, B;A.mat[1][1] = 23;                //原矩阵首元素为23,使每一列都可以被转换(原来第二列不行for (int i = 1; i <= n; i++)scanf("%d", &A.mat[i + 1][1]);A.mat[n + 2][1] = 3;for (int i = 1; i <= n + 1; i++)B.mat[i][1] = 10;for (int i = 1; i <= n + 2; i++)B.mat[i][n + 2] = 1;for (int i = 1; i < n + 2; i++)for (int j = 2; j <= i; j++)B.mat[i][j] = 1;     //转移矩阵的下三角单位阵B = powmul(B, m);A = mul(B, A);               //A除了第一列之外所有的元素都是0,相当于列矩阵cout << A.mat[n + 1][1] << endl;}return 0;}



0 0
原创粉丝点击