E. Product Oriented Recurrence
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
Let fx=c2x−6⋅fx−1⋅fx−2⋅fx−3fx=c2x−6⋅fx−1⋅fx−2⋅fx−3 for x≥4x≥4 .
You have given integers nn , f1f1 , f2f2 , f3f3 , and cc . Find fnmod(109+7)fnmod(109+7) .
Input
The only line contains five integers nn , f1f1 , f2f2 , f3f3 , and cc (4≤n≤10184≤n≤1018 , 1≤f11≤f1 , f2f2 , f3f3 , c≤109c≤109 ).
Output
Print fnmod(109+7)fnmod(109+7) .
Examples
Input
Copy
5 1 2 5 3
Output
Copy
72900
Input
Copy
17 97 41 37 11
Output
Copy
317451037
Note
In the first example, f4=90f4=90 , f5=72900f5=72900 .
In the second example, f17≈2.28×1029587f17≈2.28×1029587 .
很明显要求c的指数 f1的指数 f2的指数 f3的指数
设c 的 指数 为 An
那么 易得 An= An-1 +An-2 +An-3 +2*n-6
然后构造矩阵
1 1 0 0 0
1 0 1 0 0
1 0 0 0 0
1 0 0 1 0
1 0 0 -1/3 1
-1/3要取在mod 欧拉(1e9+7)条件下的逆元
A的初始矩阵 0 0 0 8 -6
在矩阵快速幂过程中
mod取欧拉(1e9+7)
对于f的系数 有 Fn=Fn+Fn-2+Fn-3
因为有3个 (f1,f2,f3) 初始项矩阵不同但是递推式一样
F的构造矩阵为
1 1 0
1 0 1
1 0 0
f1初始矩阵 0 0 1
f2初始矩阵 0 1 0
f3初始矩阵 1 0 0
注意欧拉降幂
直接矩阵快速幂
完后ans=c的多少次方*f1的多少次方*f2的多少次方*f3的多少次方
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
typedef long long ll;
long long mod=1e9+7;
long long qpow(long long a,long long n)
{
long long ans=1;
long long base=a;
while(n)
{
if(n&1)
ans=ans*base%mod;
base=base*base%mod;
n>>=1;
}
return ans;
}
long long ol(long long x)
{
long long i,res=x;
for(i=2;i*i<=x;i++)
{
if(x%i==0)
{
res=res-res/i;
while(x%i==0)
x/=i;
}
}
if(x>1)
res=res-res/x;
return res;
}
int N=5;
struct Matrix{///矩阵结构体
ll matrix[5][5];
};
Matrix a,b;
void init(Matrix &res)///初始化为单位矩阵
{
memset(res.matrix,0,sizeof(res.matrix));
for(int i=0;i<N;i++)
res.matrix[i][i]=1;
}
Matrix multiplicative(Matrix a,Matrix b)///矩阵乘法
{
Matrix res;
memset(res.matrix,0,sizeof(res.matrix));
for(int i = 0 ; i < N ; i++){
for(int j = 0 ; j < N ; j++){
for(int k = 0 ; k < N ; k++){
res.matrix[i][j] += a.matrix[i][k]*b.matrix[k][j];
res.matrix[i][j]+=mod;
res.matrix[i][j] %= mod;
}
}
}
return res;
}
Matrix Pow(Matrix mx,ll m)///矩阵快速幂
{
Matrix res,base=mx;
init(res);
while(m)
{
if(m&1)
res=multiplicative(res,base);
base=multiplicative(base,base);
m>>=1;
}
return res;
}
long long n,f1,f2,f3,c;
Matrix ATP,ADP,TCP,UDP;
int main()
{
//printf("%lld",ol(mod-1));
scanf("%lld%lld%lld%lld%lld",&n,&f1,&f2,&f3,&c);
memset(a.matrix,0,sizeof(a.matrix));
memset(b.matrix,0,sizeof(b.matrix));
mod-=1;
a.matrix[0][0]=1;
a.matrix[0][1]=1;
a.matrix[0][2]=1;
a.matrix[0][3]=1;
a.matrix[0][4]=1;
a.matrix[1][0]=1;
a.matrix[2][1]=1;
a.matrix[3][3]=1;
a.matrix[3][4]=(-qpow(3,(ol(mod)-1+mod)%mod)+mod)%mod;
a.matrix[4][4]=1;
b.matrix[0][0]=1;
b.matrix[0][1]=1;
b.matrix[0][2]=1;
b.matrix[1][0]=1;
b.matrix[2][1]=1;
//ATP.matrix[0][0]=0;
//ATP.matrix[1][0]=f2;
//ATP.matrix[2][0]=f1;
ATP.matrix[3][0]=8;
ATP.matrix[4][0]=(-6+mod)%mod;
Matrix op=Pow(a,n-3);
Matrix ty=multiplicative(op,ATP);
ll you=ty.matrix[0][0];
//printf("%lld\n",you);
N=3;
ll ans=1;
mod++;
ans=ans*qpow(c,you)%mod;
mod--;
ADP.matrix[2][0]=1;
TCP.matrix[1][0]=1;
UDP.matrix[0][0]=1;
Matrix tp=Pow(b,n-3);
Matrix p1=multiplicative(tp,ADP);
Matrix p2=multiplicative(tp,TCP);
Matrix p3=multiplicative(tp,UDP);
mod++;
//printf("%lld %lld %lld %lld\n",you,p1.matrix[0][0],p2.matrix[0][0],p3.matrix[0][0]);
ans=ans*qpow(f1,p1.matrix[0][0])%mod;
ans=ans*qpow(f2,p2.matrix[0][0])%mod;
ans=ans*qpow(f3,p3.matrix[0][0])%mod;
printf("%lld\n",ans);
}