【HDU - 5015 】233 Matrix (矩阵快速幂)

题干:

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 a 0,1 = 233,a 0,2 = 2333,a 0,3 = 23333...) Besides, in 233 matrix, we got ai,j = a i-1,j +a i,j-1( i,j ≠ 0). Now you have known a 1,0,a 2,0,...,a n,0, could you tell me a n,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 ≤ 10 9). The second line contains n integers, a 1,0,a 2,0,...,a n,0(0 ≤ a i,0 < 2 31).

Output

For each case, output a n,m mod 10000007.

Sample Input

1 1
1
2 2
0 0
3 7
23 47 16

Sample Output

234
2799
72937

Hint

结题报告:

         依旧是按照列,找一个转移矩阵,然后做运算,最后乘上之前保存的数组,得到想要的结果

AC代码:

#include<bits/stdc++.h>

using namespace std;
const int MAX = 20 ;
const int mod = 10000007 ;
struct Matrix {
    long long mat[MAX][MAX];
};
int n,m;
long long b[MAX];
Matrix mul(Matrix a,Matrix b)
{
    Matrix c;
    memset(c.mat,0,sizeof(c.mat));
    for(int i=0; i<=n+1; i++) {
        for(int j=0; j<=n+1; j++) {
            c.mat[i][j]=0;
            for(int k=0; k<=n+1; k++) {
                if(a.mat[i][k]&&b.mat[k][j]) {
                    c.mat[i][j]+=a.mat[i][k]*b.mat[k][j];//矩阵乘法
                    c.mat[i][j]%=mod;
                }
            }
        }
    }
    return c;//返回乘完了之后的矩阵
}
Matrix q_pow(Matrix a, int k)
{
    Matrix ans;
    memset(ans.mat,0,sizeof(ans.mat));
    for(int i=0;i<=n+1;i++)
        ans.mat[i][i]=1;
    while(k)//使用快速幂的思想进行矩阵的m次方相乘
    {
        if(k&1) {
        	ans=mul(ans,a);
    	}
		k>>=1;
        a=mul(a,a);
    }
    return ans;
}
    
int main()
{
    int m;
    Matrix a;//转移矩阵 
    while(~scanf("%d%d",&n,&m) )
    {
        //初始化第一列 //b数组就是第一列,最后与转移矩阵的m次方相乘得到anm
	    for(int i=1; i<=n; i++) {
	    	scanf("%lld",&b[i]);
		}
	    b[0]=23;
	    b[n+1]=3;
	    //求a这个转移矩阵。先初始化!因为你比如a13 这个地方的值就没有更新到,因为他是0,所以运算之后就可能改变值了,所以下一组输入的时候a13这里就不是0了,所以这里一定要memset一下。 
	    memset(a.mat,0,sizeof(a.mat));
	    for(int i = 0; i<=n; i++) {
	        a.mat[i][0]=10;
	        a.mat[i][n+1]=1;
	    }
	    a.mat[n+1][n+1]=1;
	    for(int i = 1; i<=n; i++) {
	        for(int j = 1; j<=i; j++) {
	            a.mat[i][j]=1;
	        }
	    }
        Matrix end = q_pow(a,m);
        long long ans=0;
        for(int i = 0;i<=n+1;i++) {
        	ans+=(end.mat[n][i]*b[i])%mod,ans%=mod;
		}
        printf("%lld\n",ans);
    }
    return 0;
}

 

全部评论

相关推荐

不愿透露姓名的神秘牛友
2025-12-17 16:48
今天九点半到公司,我跟往常一样先扫了眼电脑,屁活儿没有。寻思着没事干,就去蹲了个厕所,回来摸出手机刷了会儿。结果老板刚好路过,拍了我一下说上班别玩手机,我吓得赶紧揣兜里。也就过了四十分钟吧,我的直属领导把我叫到小隔间,上来就给我一句:“你玩手机这事儿把老板惹毛了,说白了,你可以重新找工作了,等下&nbsp;HR&nbsp;会来跟你谈。”&nbsp;我当时脑子直接宕机,一句话都没憋出来。后面&nbsp;HR&nbsp;找我谈话,直属领导也在旁边。HR&nbsp;说我这毛病不是一次两次了,属于屡教不改,不光上班玩手机,还用公司电脑看论文、弄学校的事儿。我当时人都傻了,上班摸鱼是不对,可我都是闲得发慌的时候才摸啊!而且玩手机这事儿,从来没人跟我说过后果这么严重,更没人告诉我在公司学个习也算犯错!连一次口头提醒都没有,哪儿来的屡教不改啊?更让我膈应的是,昨天部门刚开了会,说四个实习生里留一个转正,让大家好好表现。结果今天我就因为玩手机被开了。但搞笑的是,开会前直属领导就把我叫去小会议室,明明白白告诉我:“转正这事儿你就别想了,你的学历达不到我们部门要求,当初招你进来也没打算给你这个机会。”合着我没入贵厂的眼是吧?可我都已经被排除在转正名单外了,摸个鱼至于直接把我开了吗?真的太离谱了!
rush$0522:转正名单没进,大概率本来就没打算留你
摸鱼被leader发现了...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务