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=2otherwise fn={1,n=1ab,n=2abfn−1cfn−2,otherwise
He gives you 5 numbers n,a,b,c,p,and he will eat fn fn foods.But there are only p foods,so you should tell him fn fn 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=2otherwise fn={1,n=1ab,n=2abfn−1cfn−2,otherwise
He gives you 5 numbers n,a,b,c,p,and he will eat fn fn foods.But there are only p foods,so you should tell him fn fn 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, p p is a prime number,and p≤109+7 p≤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)两个代码的输出确不一样!!!试试吧。。。