矩阵快速幂4

目录

Power of Matrix

Yet Another Number Sequence


问题十一:

Power of Matrix

UVA - 11149

Consider an n-by-n matrix A. We define Ak = A∗A∗...∗A (k times). Here, ∗ denotes the usual matrix multiplication. You are to write a program that computes the matrix A + A2 + A3 + ... + Ak.
Example Suppose A = 
0 2 0 0 0 2 0 0 0  . Then A2 = 
0 2 0 0 0 2 0 0 0   
0 2 0 0 0 2 0 0 0  = 
0 0 4 0 0 0 0 0 0  , thus:
A + A2 = 
0 2 0 0 0 2 0 0 0  + 
0 0 4 0 0 2 0 0 0  = 
0 2 4 0 0 2 0 0 0   Such computation has various applications. For instance, the above example actually counts all the paths in the following graph:
Input
Input consists of no more than 20 test cases. The first line for each case contains two positive integers n (≤ 40) and k (≤ 1000000). This is followed by n lines, each containing n non-negative integers, giving the matrix A. Input is terminated by a case where n = 0. This case need NOT be processed.
Output
For each case, your program should compute the matrix A+A2 +A3 +...+Ak. Since the values may be very large, you only need to print their last digit. Print a blank line after each case.
Sample Input
3 2 0 2 0 0 0 2 0 0 0 0 0
Sample Output
0 2 4 0 0 2 0 0 0


题意:给你n,k。有n组数据计算A+A^{2}+A^{3}+\cdots +A^{k}的值

分析:这道题两次二分,相当经典。首先我们知道,A^i可以二分求出。然后我们需要对整个题目的数据规模k进行二分。比如,当k=6时,有:
  A + A^2 + A^3 + A^4 + A^5 + A^6 =(A + A^2 + A^3) + A^3*(A + A^2 + A^3)
应用这个式子后,规模k减小了一半。我们二分求出A^3后再递归地计算A + A^2 + A^3,即可得到原问题的答案。

奇数: F[n]=F[n-1]+A^n        

偶数: F[n]=F[n/2]+F[n/2]*An/2

代码:

#include<stdio.h>
#include<string.h>
#define N 31
struct Matrix
{
    int a[N][N];
}res,origin,tmp,A,B,C,ans;
int n,m;
Matrix mul(Matrix x,Matrix y)   //矩阵乘法
{
    int i,j,k;
    memset(tmp.a,0,sizeof(tmp.a));
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
            for(k=1;k<=n;k++)
            {
                tmp.a[i][j]+=(x.a[i][k]*y.a[k][j]);
                tmp.a[i][j]%=m;
            }
    return tmp;
}
Matrix quickpow(Matrix origin,int k)   //矩阵快速幂
{
    int i;
    memset(res.a,0,sizeof(res.a));
    for(i=1;i<=n;i++)
        res.a[i][i]=1;
    while(k)
    {
        if(k&1)
            res=mul(res,origin);
        origin=mul(origin,origin);
        k>>=1;
    }
    return res;
}
Matrix sum(Matrix x,Matrix y)   //矩阵求和
{
    int i,j;
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
            tmp.a[i][j]=(x.a[i][j]+y.a[i][j])%m;
    return tmp;
}
Matrix bin(int k)
{
    if(k<=1)
        return A;
    else if(k%2)   //奇数:F[n]=F[n-1]+A^n   
    {
        B=bin(k-1);
        C=quickpow(A,k);   
        return sum(B,C);
    }
    else     //偶数: F[n]=F[n/2]+F[n/2]*A^(n/2)
    {
        B=bin(k/2);
        C=quickpow(A,k/2);
        C=mul(C,B);
        return sum(B,C);
    }
}
int main()
{
    int i,j,k;
    scanf("%d%d%d",&n,&k,&m);
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
            scanf("%d",&A.a[i][j]);
    ans=bin(k);   //二分
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
            if(j<n)
                printf("%d ",ans.a[i][j]);
            else
                printf("%d\n",ans.a[i][j]);
    }
    return 0;
}

问题十二:

Yet Another Number Sequence

CodeForces - 392C

Everyone knows what the Fibonacci sequence is. This sequence can be defined by the recurrence relation:

F1 = 1, F2 = 2, Fi = Fi - 1 + Fi - 2 (i > 2).

We'll define a new number sequence Ai(k) by the formula:

Ai(k) = Fi × ik (i ≥ 1).

In this problem, your task is to calculate the following sum: A1(k) + A2(k) + ... + An(k). The answer can be very large, so print it modulo 1000000007 (109 + 7).

Input

The first line contains two space-separated integers n, k (1 ≤ n ≤ 1017; 1 ≤ k ≤ 40).

Output

Print a single integer — the sum of the first n elements of the sequence Ai(k) modulo 1000000007 (109 + 7).

Examples

Input

1 1

Output

1

Input

4 1

Output

34

Input

5 2

Output

316

Input

7 4

Output

73825

题意:给出n,k。求F_{i}×i^{k}的前n项和。

分析链接:优美的Fibonacci数列与矩阵

如何构造矩阵链接:根据递推公式构造系数矩阵用于快速幂

代码:

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;
typedef long long LL;
const int mod = 1e9 + 7;
int len;
LL n, k, c[45][45];
struct matrix {
	LL m[100][100];
}mc,I;
matrix multi(matrix a, matrix b) {
	matrix ans;
	for (int i = 0; i < len; i++) {
		for (int j = 0; j < len; j++) {
			ans.m[i][j] = 0;
			for (int k = 0; k < len; k++) {
				ans.m[i][j] = (ans.m[i][j] + (a.m[i][k] * b.m[k][j]) % mod) % mod;
			}
		}
	}
	return ans;
}
matrix quick(matrix a, LL n) {
	matrix ans = I, t = a;
	while (n>0) {
		if (n & 1)
			ans = multi(ans, t);
		t = multi(t, t);
		n >>= 1;
	}
	return ans;
}
int main()
{
	c[0][0] = 1; c[1][0] = 1; c[1][1] = 1;
	for (int i = 2; i <= 40; i++) {
		for (int j = 0; j <= i; j++) {
			if (j == 0 || j == i)
				c[i][j] = 1;
			else
				c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
		}
	}
	for (int i = 0; i <= 40; i++) {
		I.m[i][i] = 1;
	}
	while (cin >> n >> k) {
		memset(mc.m, 0, sizeof(mc.m));
		len = 2 * k + 3;
		mc.m[0][0] = 1;
		for (int j = 0; j <= k; j++) {
			mc.m[0][j + 1] = c[k][j];
			mc.m[0][j + k + 2] = c[k][j];
		}
		mc.m[1][1] = 1; mc.m[1][k + 2] = 1;
		for (int i = 1; i <= k; i++)
			for (int j = 0; j <= i; j++) {
				mc.m[i + 1][j + 1] = c[i][j];
				mc.m[i + 1][j + k + 2] = c[i][j];
			}
		mc.m[k + 2][1] = 1;
		for (int i = 1; i <= k; i++) {
			for (int j = 0; j <= i; j++) {
				mc.m[i + k + 2][j + 1] = c[i][j];
			}
		}
		mc = quick(mc, n - 1);
		LL ans = 0;
		for (int i = 0; i < len; i++) {
			ans = (ans + mc.m[0][i] % mod) % mod;
		}
		cout << ans << endl;
	}
	return 0;
}

大佬博客矩阵十题:https://www.cnblogs.com/frog112111/archive/2013/05/16/3082416.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值