首页 > 其他分享 >k次幂(构造矩阵的技巧)

k次幂(构造矩阵的技巧)

时间:2024-08-18 20:26:49浏览次数:10  
标签:技巧 .. int res 矩阵 构造 .....

第2题     k次幂 查看测评数据信息

image.png

输入格式

 

一行,两个整数,n和k。  1<=n<=1000000000,   1<=k<=50。

答案模1000000007。

 

输出格式

 

一个整数。

 

输入/输出例子1

输入:

5 1

 

输出:

15

 

样例解释

 

 

先考虑dp

f(i): 1^k+2^k+...+i^k
f(i)=f(i-1)+i^k

 

矩阵加速:
[f(i-1), i^k] * [ ] = [f(i), (i+1)^k]
(i+1)^k比较难求,我们展开(二项式定理)

(i+1)^k=C(k, 1)*i + C(k, 2)*i^2 + C(k, 3)*i^3 .....  +C(k, k-1)*i^(k-1) + C(k, k)*i^k
组合数可以预处理,但是i^(k-1), i^(k-2)....i^0怎么算?

好像没法算。所以必须放在矩阵中维护。


[f(i-1), i^k, i^(k-1),i^(k-2),.....,i^0]
* [ ] =
[f(i), (i+1)^k, (i+1)^(k-1),(i+1)^(k-2),.....,(i+1)^0]

那么(i+1)^k就够算了嘛!

我们再看看(i+1)^(k-1)如何算

展开,发现条件全部已知了。

(i+1)^(k-1)=  C(k-1, 1)*i + C(k-1, 2)*i^2 + ...... + C(k-1, k-2)*i^(k-2) + C(k-1, k-1)*i^(k-1)

 

这个时候可以构造未知矩阵了:

第一列特殊一点,根据“f(i)=f(i-1)+i^k”来填

第二列往后开始有规律了

(i+1)^k,首先肯定不需要f(i-1),然后按照二项式定理展开,

(i+1)^k=C(k, 1)*i + C(k, 2)*i^2 + C(k, 3)*i^3 .....  +C(k, k-1)*i^(k-1) + C(k, k)*i^k

根据上面的式子又可以继续填了。

然后到第三列,第四列同理。先展开,再填。

[1, 0,             0                          .. ]
[1, C(k, k),    0                           .. ]
[0, C(k, k-1), C(k-1, k-1)            .. ]
[0, C(k, k-2), C(k-1, k-1-1)           ]
[. .. .. .. ]
[. .. .. .. ]
[. .. .. .. ]
[0 C(k, k-k),   C(k-1, k-1-(k-1)) .. ]

 

当i=1时,
[0, 1, 1, 1......1] * [] = [结果]

 

 

注意一下,

本代码和构造矩阵有点不一样,是以

[1, 0,             0                           .. ]
[1, C(k, 0),    0                           .. ]
[0, C(k, 1), C(k-1, 0)                  .. ]
[0, C(k, 2), C(k-1, 1)                     ]
[. .. .. .. ]
[. .. .. .. ]
[. .. .. .. ]
[0 C(k, k),   C(k-1, k-1)              .. ]

构造的,但其实本质一样,因为C(n, r)=C(n, n-r)

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=105, Mod=1000000007;

struct mp
{
	int n, m;
	int a[N][N];
	
	void init(int row, int col, bool isI)
	{
		n=row, m=col;
		memset(a, 0, sizeof a);
		
		if (isI)
			for (int i=1; i<=row; i++) a[i][i]=1;
	}	
}A, B;
mp operator * (const mp A, const mp B)
{
	mp C;
	C.init(A.n, B.m, 0);
	for (int i=1; i<=A.n; i++)
		for (int j=1; j<=B.m; j++)
			for (int k=1; k<=A.m; k++)
				C.a[i][j]=(C.a[i][j]+A.a[i][k]*B.a[k][j])%Mod;
		
	return C;
}
mp qpow_mp(mp A, int k)
{
	mp res;
	res.init(A.n, A.m, 1);
	while (k>0)
	{
		if (k&1) res=res*A;
		A=A*A;
		k>>=1;
	}
	
	return res;
}
int n, k, yh[N][N];
signed main()
{
	scanf("%lld%lld", &n, &k);
	A.init(1, 2+k, 0);
	A.a[1][1]=0;
	for (int i=2; i<=2+k; i++) A.a[1][i]=1;
	
	for (int i=1; i<=100; i++)
	{
		yh[i][i]=yh[i][1]=1;
		for (int j=2; j<i; j++) yh[i][j]=(yh[i-1][j]+yh[i-1][j-1])%Mod;
	}
	
	B.init(2+k, 2+k, 0);
	B.a[1][1]=B.a[2][1]=1;
	for (int i=2; i<=2+k; i++)
		for (int j=i; j<=2+k; j++)
			B.a[j][i]=yh[k-i+2+1][j-i+1];
			
	A=A*qpow_mp(B, n);
		
	printf("%lld", A.a[1][1]);
	return 0;
}

  

 

 

 

标签:技巧,..,int,res,矩阵,构造,.....
From: https://www.cnblogs.com/didiao233/p/18366038

相关文章

  • 矩阵前k次幂之和(矩阵套矩阵的技巧)
    第1题   矩阵前k次幂之和 查看测评数据信息给出一个n*n的矩阵A,求A^1+A^2+A^3+...+A^k。输入格式 第一行,两个整数,n和k。1<=n<=30, 1<=k<=1000000000。接下来是n行n列的矩阵A。 输出格式 输出最后的矩阵,每个元素都是模1000000007。 输入/输......
  • 序列(dp+矩阵加速)
    第2题   序列 查看测评数据信息给定一个数集A,现在你需要构造一个长度为k的序列B,序列B的元素从数集A中任意挑选,要求B中任意相邻的两个数字的异或值二进制表示中1的个数是3的倍数,请问B的有多少种合法的构造方案?两种方案不同当且仅当存在B[i]在A中的位置不同。输入格式......
  • 幸运数(dp+矩阵加速)
    第1题   幸运数 查看测评数据信息小明认为只有数字4和7是幸运数字,其他数字都不是。如果一个整数的每个数字都是幸运数字,那么该整数就是幸运整数。给出一个数组numbers[1...n]。一个长度为L的幸运数列A[0],A[1],A[2],...A[L-1]必须同时满足:1、对于0<=i<L,    A[......
  • 呆头鹅矩阵系统:短视频运营的创新之选——下载-官网-源码
    在短视频占据互联网重要地位的当下,呆头鹅矩阵系统以其创新的功能和可靠的保障,成为企业打开知名度、实现精准获客的强大工具。呆头鹅矩阵系统为用户提供了高效的短视频矩阵管理方案。它如同一个强大的指挥中心,将多个短视频平台的账号集中管理,无需繁琐地在多个手机上切换登录账......
  • 谷歌实用Gmail技巧:批量使用多个外贸邮箱技巧
    如果你是外贸营销人员,您是否觉得在多个Gmail帐户之间来回切换、在无数个浏览器标签中搜索关键邮件非常费劲?或者您是否经常误操作导致账号被封?这个问题太常见了,但是其实有一些工具可以简化了管理多个Gmail帐户的过程,并且防止账号关联,下面具体展开说说。如何在Gmail中使用......
  • 螺旋矩阵(LeetCode)
    题目给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。解题defspiralOrder(matrix):ifnotmatrixornotmatrix[0]:return[]top,bottom=0,len(matrix)-1left,right=0,len(matrix[0])-1......
  • 【时时三省】(C语言基础)调试技巧2
    山不在高,有仙则名。水不在深,有龙则灵。             ----CSDN时时三省多多动手,尝试调试,才能有进步。•一定要熟练掌握调试技巧。•初学者可能80%的时间在写代码,20%的时间在调试。但是一个程序员可能20%的时间在写程序,但是80%的时间在调试。•我......
  • 【C语言初阶】掌握C语言调试技巧,迈向高效编程的阶梯
    ......
  • 旋转矩阵的行列式为什么一定要等于1?
    一.为什么旋转矩阵要等于1?旋转概念:“旋转”就是一种没有拉伸或压缩的变换,|A|就只能是±1中的一个了。成为旋转矩阵的条件:正常情况下,求的旋转矩阵是不会出现-1这种情况的。det®=-1则表明R无效。解释:一个矩阵要能成为一个旋转矩阵,则它在构造上必定是正交矩阵,同时还是矩阵的每个......
  • 「OC」探索CALayer:基础知识与实用技巧简要介绍
    「OC」探索CALayer:基础知识与实用技巧简要介绍文章目录「OC」探索CALayer:基础知识与实用技巧简要介绍前言认识CALayerCALayer的相关属性UIView和CALayer区别联系创建UIView和CALayer的原因开始创建CALayer视图层级CALayers和Sublayersposition与anchorPoint(锚点)CGIm......