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;
}
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18169996,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。