Holion August will eat every thing he has found.
Now there are many foods,but he does not want to eat all of them at once,so he find a sequence.
fn=⎧⎩⎨⎪⎪1,ab,abfcn−1fn−2,n=1n=2otherwisefn={1,n=1ab,n=2abfn−1cfn−2,otherwise
He gives you 5 numbers n,a,b,c,p,and he will eat fnfn foods.But there are only p foods,so you should tell him fnfn mod p.
Now there are many foods,but he does not want to eat all of them at once,so he find a sequence.
fn=⎧⎩⎨⎪⎪1,ab,abfcn−1fn−2,n=1n=2otherwisefn={1,n=1ab,n=2abfn−1cfn−2,otherwise
He gives you 5 numbers n,a,b,c,p,and he will eat fnfn foods.But there are only p foods,so you should tell him fnfn mod p.
Each testcase has 5 numbers,including n,a,b,c,p in a line.
1≤T≤10,1≤n≤1018,1≤a,b,c≤109 1≤T≤10,1≤n≤1018,1≤a,b,c≤109,pp is a prime number,and p≤109+7p≤109+7.
1 5 3 3 3 233
190
(ab)p[n]= ab * ((ab)p[n-1])c *
((ab)p[n-2]);递推式子可以这样写;
合并后变为(ab)p[n]=(ab)(c*p[n-1]+p[n-2]+1);
可以得到p[n]=c*p[n-1]+p[n-2]+1;
Fn=Fn-1*c+Fn-2+b;
然后我们也不难写出矩阵:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
struct matrix
{
ll a[3][3];
};
ll mod;
matrix A,B;
matrix mul(matrix aa,matrix bb)
{
matrix res;
memset(res.a,0,sizeof(res.a));
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{
for(int k=0; k<3; k++)
{
res.a[i][j]=(res.a[i][j]+aa.a[i][k]*bb.a[k][j])%mod;
}
}
}
return res;
}
matrix pow(matrix aa,ll p)
{
matrix res;
memset(res.a,0,sizeof(res.a));
for(int i=0; i<3; i++)
res.a[i][i]=1;
while(p)
{
if(p&1)
res=mul(res,aa);
p>>=1;
aa=mul(aa,aa);
}
return res;
}//矩阵快速幂
ll mod_pow(ll x,ll n,ll mod)
{
ll res=1;
while(n>0)
{
if(n&1)
res=res*x%mod;
x=x*x%mod;
n>>=1;
}
return res;
}
int main()
{
ll n,a,b,c,t;
cin>>t;
while(t--)
{
cin>>n>>a>>b>>c>>mod;
A.a[0][0]=c;
A.a[0][1]=1;
A.a[0][2]=b;
A.a[1][0]=1;
A.a[1][1]=0;
A.a[1][2]=0;
A.a[2][0]=0;
A.a[2][1]=0;
A.a[2][2]=1;
if(n==1)
cout<<"1"<<endl;
else if(n==2)
cout<<mod_pow(a,b,mod);
else
{
mod--;
B =pow(A,(n - 2));
ll tmp=B.a[0][0]*b+B.a[0][2];
mod++;
ll ans = mod_pow(a, tmp, mod);
cout<<ans<<endl;
}
}
return 0;
}
另一种方法:(同样AC)
#include <bits/stdc++.h>
using namespace std;
const int N=1e4+5;
typedef long long ll;
const int mod=1e9+7;
ll n,a,b,c,p;
struct matrix
{
ll a[3][3];
};
matrix A;
void Iint(ll x)//矩阵初始化;
{
A.a[0][0]=x;
A.a[0][1]=1;
A.a[0][2]=1;
A.a[1][0]=1;
A.a[1][1]=A.a[1][2]=0;
A.a[2][0]=A.a[2][1]=0;
A.a[2][2]=1;
}
matrix mul(matrix x,matrix y)//矩阵相乘
{
matrix ans;
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
ans.a[i][j]=0;
for(int k=0;k<3;k++)
{
ans.a[i][j]+=(x.a[i][k]*y.a[k][j])%(p-1);
ans.a[i][j]%=(p-1);
}
}
}
return ans;
}
ll fast_fun(matrix temp,ll num)//矩阵快速幂;
{
matrix s,base;
for(int i=0;i<3;i++)//s初始化为单位矩阵
{
for(int j=0;j<3;j++)
{
s.a[i][j]=0;
base.a[i][j]=temp.a[i][j];
}
}
s.a[0][0]=s.a[1][1]=s.a[2][2]=1;
while(num)
{
if(num&1)
{
s=mul(s,base);
}
base=mul(base,base);
num=(num>>1);
}
return (s.a[0][0]+s.a[0][2])%(p-1);
}
ll fastpow(ll fx,ll fy)//快速幂求结果;
{
ll s=1,base=fx;
while(fy)
{
if(fy&1)
{
s*=base;
s%=p;
}
base*=base;
base%=p;
fy=(fy>>1);
}
return s;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld%lld%lld%lld",&n,&a,&b,&c,&p);
Iint(c);
if(n==1)printf("1\n");
else if(n==2)printf("%lld\n",fastpow(a,b));
else
{
if(a%p==0)printf("0\n");
else {
ll gg=fast_fun(A,n-2)*b%(p-1);
printf("%lld\n",fastpow(a,gg));
}
}
}
return 0;
}
两种代码都能ac 但是有趣的是(3 2 2 2 2)两个代码的输出确不一样!!!试试吧。。。
本文介绍了一种使用矩阵快速幂解决特定递归数列问题的方法,并提供了两种不同的实现方式,详细展示了如何通过矩阵运算来高效计算大规模项值。
396

被折叠的 条评论
为什么被折叠?



