ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

题解【P5004 专心OI - 跳房子】

2022-09-15 12:03:03  阅读:252  来源: 互联网

标签:bmatrix return Matrix OI int 题解 rep 矩阵 P5004


本题的找规律题解到此为止。

为防止新人受到误导,不再接受新的此类题解。

以前的保留不会删除,但请不要再提交。


题目传送门

矩阵加速模板题吧。给一个正经的不用找规律的做法。

考虑设 \(F_n\) 表示前 \(n\) 个格子的答案,\(f_n\) 表示最后降落在 \(n\) 的方案数,显然有 \(F_n=F_{n-1}+f_n\),由于 \(f_n\) 也是由一个 \(f\) 的前缀和得来,所以得到 \(F_{n}=F_{n-1}+F_{n-m-1}\)。

这个长得就很矩阵加速了。观察数据范围发现 \(m\) 很小,而这又是一个前缀和的形式,启示我们把 \(\{F_n,F_{n-1},\cdots,F_{n-m}\}\) 都放入一个矩阵里进行转移。

考虑用原矩阵 \(\begin{bmatrix} F_{n-1}\\ F_{n-2}\\ \cdots\\ F_{n-m-1} \end{bmatrix}\) 推出目标矩阵 \(\begin{bmatrix} F_{n}\\ F_{n-1}\\ \cdots\\ F_{n-m} \end{bmatrix}\)

对于 \(i\) 满足 \(n-m\le i\le n-1\),\(F_i\) 都是原矩阵已知的元素,不用管它。

对于 \(F_n\),把它直接替换成 \(F_{n-1}+F_{n-m-1}\),这两项恰好也是我们原矩阵已知的元素。

下面构造转移矩阵。

第一行是特殊的,因为它的转移是对于 \(F_n\) 的。我们将第一个设成 \(1\),最后一个设成 \(1\),其余设成 \(0\),表示对应 \(F_{n-1}\) 和 \(F_{n-m-1}\)。

然后剩下的那些行,只需要将 \(F_i\) 对应的位置设成 \(1\) 就可以,直接继承过来。

这样就得到了这样一个矩阵(这是当 \(m=5\) 时矩阵的样子,来类比一下,应该很容易能看出来):

\[\begin{bmatrix} 1 & 0 & 0 & 0 & 0 & 1\\ 1 & 0 & 0 & 0 & 0 & 0\\ 0 & 1 & 0 & 0 & 0 & 0\\ 0 & 0 & 1 & 0 & 0 & 0\\ 0 & 0 & 0 & 1 & 0 & 0\\ 0 & 0 & 0 & 0 & 1 & 0 \end{bmatrix}\]

这样的话,可以构造一个 \(\left(m+1\right)\times \left(m+1\right)\) 的转移矩阵然后快速幂即可。

矩阵乘法 \(\Theta(m^3)\),快速幂 \(\Theta(\log n)\),最终复杂度 \(\Theta(m^3\log n)\)。

代码:

const int MOD(1e9+7);

inline int add(int x,int y){return x+y>=MOD?x+y-MOD:x+y;}
inline int mul(int x,int y){return 1ll*x*y%MOD;}

ll n;
int m;

struct Matrix
{
	int G[30][30];
	Matrix(){rep(i,1,m) rep(j,1,m) G[i][j]=0;return;}
	Matrix operator*(const Matrix&x)
	{
		Matrix res;
		rep(i,1,m) rep(j,1,m) rep(k,1,m) res.G[i][j]=add(res.G[i][j],mul(G[i][k],x.G[k][j]));
		return res;
	}
};

inline Matrix ksm(ll y)
{
	Matrix ans,x;
	rep(i,1,m) ans.G[i][i]=1;
	rep(i,2,m) x.G[i][i-1]=1;
	x.G[1][1]=1,x.G[1][m]=1;
	while(y)
	{
		if(y&1) ans=ans*x;
		x=x*x;
		y>>=1;
	}
	return ans;
}

int main()
{
	scanf("%lld%d",&n,&m);
	++m;
	Matrix now=ksm(n+m-1);
	printf("%d\n",now.G[1][1]);
	return 0;
}

标签:bmatrix,return,Matrix,OI,int,题解,rep,矩阵,P5004
来源: https://www.cnblogs.com/UperFicial/p/16696073.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有