UVA10870 Recurrences 题解

题目传送门

前置知识

矩阵加速递推

解法

直接递推显然不可做,考虑矩阵加速递推。

\(F_{n}=\begin{bmatrix} f_{n} & f_{n+1} & f_{n+2} & \dots & f_{n+d-1} \end{bmatrix}\),容易有 \(\begin{aligned} F_{n} &=\begin{bmatrix} f_{n} & f_{n+1} & f_{n+2} & \dots & f_{n+d-1} \end{bmatrix} \\ &=\begin{bmatrix} f_{n-1} & f_{n} & f_{n+1} & \dots & f_{n+d-2} \end{bmatrix} \times \begin{bmatrix} 0 & 0 & 0 & \dots & a_{d} \\ 1 & 0 & 0 & \dots & a_{d-1} \\ 0 & 1 & 0 & \dots & a_{d-2} \\ \dots & \dots & \dots & \dots & \dots & \\ 0 & 0 & 0 & \dots & a_{1} \end{bmatrix} \\ &=\begin{bmatrix} f_{n-2} & f_{n-1} & f_{n} & \dots & f_{n+d-3} \end{bmatrix} \times \begin{bmatrix} 0 & 0 & 0 & \dots & a_{d} \\ 1 & 0 & 0 & \dots & a_{d-1} \\ 0 & 1 & 0 & \dots & a_{d-2} \\ \dots & \dots & \dots & \dots & \dots & \\ 0 & 0 & 0 & \dots & a_{1} \end{bmatrix}^{2} \\ &= \dots \\ &=\begin{bmatrix} f_{1} & f_{2} & f_{3} & \dots & f_{d} \end{bmatrix} \times \begin{bmatrix} 0 & 0 & 0 & \dots & a_{d} \\ 1 & 0 & 0 & \dots & a_{d-1} \\ 0 & 1 & 0 & \dots & a_{d-2} \\ \dots & \dots & \dots & \dots & \dots & \\ 0 & 0 & 0 & \dots & a_{1} \end{bmatrix}^{n-1} \\ &=F_{1} \times \begin{bmatrix} 0 & 0 & 0 & \dots & a_{d} \\ 1 & 0 & 0 & \dots & a_{d-1} \\ 0 & 1 & 0 & \dots & a_{d-2} \\ \dots & \dots & \dots & \dots & \dots & \\ 0 & 0 & 0 & \dots & a_{1} \end{bmatrix}^{n-1} \end{aligned}\)

接着矩阵快速幂处理即可。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define ull unsigned long long
#define sort stable_sort 
#define endl '\n'
struct Matrix
{
	ll ma[20][20];
	Matrix()
	{
		memset(ma,0,sizeof(ma));
	}
}f,a;
Matrix mul(Matrix a,Matrix b,ll n,ll m,ll k,ll p)
{
	Matrix c;
	for(ll i=1;i<=n;i++)
	{
		for(ll j=1;j<=k;j++)
		{
			for(ll h=1;h<=m;h++)
			{
				c.ma[i][j]=(c.ma[i][j]+(a.ma[i][h]%p)*(b.ma[h][j]%p)%p)%p;
			}
		}
	}
	return c;
}
Matrix qpow(Matrix a,ll b,ll p,ll n)
{
	Matrix ans;
	for(ll i=1;i<=n;i++)
	{
		ans.ma[i][i]=1;
	}
	while(b>0)
	{
		if(b&1)
		{
			ans=mul(ans,a,n,n,n,p);
		}
		b>>=1;
		a=mul(a,a,n,n,n,p);
	}
	return ans;
}
int main()
{
	ll n,m,b,k,p,i,j;
	while(cin>>m>>b>>p)
	{
		if(m==0&&b==0&&p==0)
		{
			break;
		}
		else
		{
			n=1;
			k=m;
			b--;
			for(i=1;i<=m;i++)
			{
				for(j=1;j<=m;j++)
				{
					a.ma[i][j]=0;
				}
			}
			for(i=m;i>=1;i--)
			{
				cin>>a.ma[i][m];
			}
			for(i=1;i<=m;i++)
			{
				cin>>f.ma[1][i];
			}
			for(i=1;i<=m-1;i++)
			{
				a.ma[i+1][i]=1;
			}
			cout<<mul(f,qpow(a,b,p,m),n,m,k,p).ma[1][1]<<endl;
		}
	}
	return 0;
}
posted @ 2024-05-02 10:28  hzoi_Shadow  阅读(7)  评论(0编辑  收藏  举报
扩大
缩小