题目
思路来源
涛神+贤神
题解
先构造出g(x)的系数矩阵,计算出cnum,num[1],num[2]和num[3]
在要算g(x)的时候,偷梁换柱成f(x)计算,加上费马小定理降幂即可
题解有左右同乘,令
,则
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
const int maxn=5;
const int mod=1e9+6;
const int MOD=1e9+7;
struct mat
{
ll a[maxn][maxn];
mat()
{
memset(a,0,sizeof a);
}
void clear()
{
memset(a,0,sizeof a);
}
};
mat operator*(mat a,mat b)
{
mat c;
for(int i=0;i<=4;++i)
{
for(int j=0;j<=4;++j)
{
for(int k=0;k<=4;++k)
{
c.a[i][j]+=a.a[i][k]%mod*b.a[k][j]%mod;
c.a[i][j]=(c.a[i][j]%mod+mod)%mod;
}
}
}
return c;
}
mat modpow(mat x,ll p)
{
mat res;
for(int i=0;i<=4;++i)
res.a[i][i]=1;
for(;p;x=x*x,p/=2)
if(p&1)res=res*x;
return res;
}
ll modpow(ll x,ll n,ll p)
{
ll res=1;
for(;n;x=x*x%p,n/=2)
if(n&1)res=res*x%p;
return res;
}
mat b;
ll n,a[maxn],c;
ll cnum,num[maxn];
ll res;
void init()
{
b.a[0][0]=1;b.a[0][1]=1;b.a[0][2]=1;b.a[0][3]=2;b.a[0][4]=-4;
b.a[1][0]=1;
b.a[2][1]=1;
b.a[3][3]=1;b.a[3][4]=1;
b.a[4][4]=1;
}
int main()
{
scanf("%I64d",&n);
scanf("%I64d%I64d%I64d%I64d",&a[1],&a[2],&a[3],&c);
if(n<=3)
{
printf("%I64d\n",a[n]);
return 0;
}
init();
mat ans;
for(int i=0;i<=5;++i)
ans.a[i][i]=1;
ans=modpow(b,n-3);
//费马小定理 系数模(1e9+6) 算值模(1e9+7)
cnum=(ans.a[0][3]*3+ans.a[0][4])%mod;
num[3]=ans.a[0][0];
num[2]=ans.a[0][1];
num[1]=ans.a[0][2];
res=1;
for(int i=1;i<=3;++i)
res=res*modpow(a[i],num[i],MOD)%MOD;
res=res*modpow(c,cnum,MOD)%MOD;
printf("%I64d\n",res);
return 0;
}