由于n<=10^9 ,显然线性推是不可能的。假如,当n很小的时候,同2663题,我们可以用dp的方式做。那么,我们可以打表,找出小数据的一些值,找出规律。f[n]=f[n-1]+5*f[n-2]+f[n-3]-f[n-4]。
以上式子是线性的关系,显然可以构造矩阵。
#include<iostream>
#include<iostream>
#include<string>
#include<stdio.h>
#include<string.h>
#include<vector>
#include<math.h>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
#define MAXN 16
#define LL __int64
const int INF=0x3f7f7f7f;
int mod;
class Matrix
{
public:
int a[MAXN][MAXN];
Matrix()
{
memset(a,0,sizeof(a));
}
Matrix(int x)
{
memset(a,0,sizeof(a));
if(x==1)
for(int i=0;i<MAXN;i++)
a[i][i]=1;
}
Matrix operator +(const Matrix &b)const
{
Matrix temp;
for(int i=1;i<MAXN;i++)
{
for(int j=1;j<MAXN;j++)
{
temp.a[i][j]=a[i][j]+b.a[i][j];
}
}
return temp;
}
Matrix operator -(const Matrix &b)const
{
Matrix temp;
for(int i=1;i<MAXN;i++)
{
for(int j=1;j<MAXN;j++)
{
temp.a[i][j]=a[i][j]-b.a[i][j];
}
}
return temp;
}
Matrix operator *(const Matrix &b)const
{
Matrix temp;
for(int i=1;i<MAXN;i++)
{
for(int j=1;j<MAXN;j++)
{
for(int k=1;k<MAXN;k++)
{
temp.a[i][j]+=(a[i][k]*b.a[k][j])%mod;
while(temp.a[i][j]<0)
temp.a[i][j]+=mod;
temp.a[i][j]%=mod;
}
}
}
return temp;
}
Matrix mat_pow(Matrix x,int n)
{
Matrix ans(1);
while(n)
{
if(n%2)
ans=ans*x;
x=x*x;
n>>=1;
}
return ans;
}
};
Matrix temp;
Matrix ans;
int main()
{
int n,i,j;
while(scanf("%d%d",&n,&mod)!=EOF)
{
if(n==0&&mod==0)break;
if(n==1)
{
printf("%d\n",1%mod);
continue;
}
if(n==2)
{
printf("%d\n",5%mod);
continue;
}
if(n==3)
{
printf("%d\n",11%mod);
continue;
}
if(n==4)
{
printf("%d\n",36%mod);
continue;
}
temp=temp.mat_pow(temp,n-4);
ans=temp*ans;
printf("%d\n",ans.a[1][1]%mod);
}
return 0;
}