题目链接:
UVA 10870 Recurrences
题意:
给出递推式:
f(n)=a1∗f(n−1)+a2∗f(n−2)+a3∗f(n−3)+...+ad∗f(n−d),n>d
其中
a1,a2,a3...ad
以及
f(1),f(2),f(3)...f(3)
已知,试求
f(n)modm.
分析:
构造矩阵和快速幂。
d∗d
阶矩阵乘以
d∗1
阶矩阵
| 0 1 0 0 ... 0 | | f(1) | | f(2) |
| 0 0 1 0 ... 0 | | f(2) | | f(3) |
| 0 0 0 1 ... 0 | * | f(3) | = | f(4) |
| . . . . . . . . . . | | .... | | .... |
| 0 0 0 0 ... 1 | | f(d-1) | | f(d) |
| ad a(d-1) a(d-2) a(d-3) a1 | | f(d) | | f(d+1) |
然后依次类推。
//0K 69MS
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
long long d,n,mod,t;
struct Matrix{
int row,col;
long long data[20][20];
};
inline Matrix multiply(Matrix a,Matrix b)
{
Matrix ans;
ans.row=a.row,ans.col=b.col;
memset(ans.data,0,sizeof(ans.data));
for(int i=1;i<=ans.row;i++){
for(int j=1;j<=ans.col;j++){
for(int k=1;k<=a.col;k++){
ans.data[i][j]+=a.data[i][k]*b.data[k][j]%mod;
ans.data[i][j]%=mod;
}
}
}
return ans;
}
inline Matrix quick_power(Matrix a,long long m)
{
Matrix ans,tmp=a;
ans.row=ans.col=a.row;
memset(ans.data,0,sizeof(ans.data));
for(int i=1;i<=ans.row;i++)
ans.data[i][i]=1;
while(m){
if(m&1) ans=multiply(ans,tmp);
tmp=multiply(tmp,tmp);
m>>=1;
}
return ans;
}
inline void debug(Matrix a,int cases)
{
printf("Case %d:\n",cases);
for(int i=1;i<=a.row;i++){
for(int j=1;j<=a.col;j++){
printf("%lld ",a.data[i][j]);
}
printf("\n");
}
printf("*************\n");
}
int main()
{
//freopen("Kin.txt","r",stdin);
while(~scanf("%lld%lld%lld",&d,&n,&mod)&&(d||n||mod)){
Matrix ans,tmp;
ans.row=ans.col=d;
tmp.row=d,tmp.col=1;
memset(ans.data,0,sizeof(ans.data));
for(int i=1;i<ans.row;i++)
ans.data[i][i+1]=1;
for(int j=ans.col;j>=1;j--){
scanf("%lld",&t);
ans.data[ans.row][j]=(t%mod+mod)%mod;
}
//debug(ans,1);
for(int i=1;i<=tmp.row;i++){
scanf("%lld",&t);
tmp.data[i][1]=(t%mod+mod)%mod;
}
//debug(tmp,2);
if(n<=d){
printf("%lld\n",tmp.data[n][1]);
continue;
}
ans=quick_power(ans,n-d);
//debug(ans,3);
tmp=multiply(ans,tmp);
//debug(tmp,4);
printf("%lld\n",(tmp.data[d][1]%mod+mod)%mod);
}
return 0;
}