E. Product Oriented Recurrence (矩阵快速幂新模板)

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.

仔细观察可以发现

其实f(n) 可以拆成 c^x1+f1^x2+f2^x3+f4^x4

我们只需要用递推式来求出x1 x2 x3 x4即可

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=5;
const long long mod=1e9+6;
const long long mod1=1e9+7;
struct node
{
    long long a[maxn][maxn];
}pos;
node milt(node x,node y)
{
    node res;
    memset(res.a,0,sizeof(res.a));
    for(int i=0;i<maxn;i++)
        for(int j=0;j<maxn;j++)
            for(int k=0;k<maxn;k++)
                res.a[i][j]=(res.a[i][j]+x.a[i][k]*y.a[k][j])%mod;
    return res;
}
node power(node mat,long long n)
{
    node x,y;
    memset(x.a,0,sizeof(x.a));
    memset(y.a,0,sizeof(y.a));
    y=mat;
    for(int i=0;i<maxn;i++) x.a[i][i]=1;
    while(n!=0)
    {
        if(n%2==1) x=milt(x,y);
        y=milt(y,y);
        n/=2;
    }
    return x;
}
long long quick_pow(long long a,long long b)
{
    long long ans=1;
    a=a%mod1;
    while(b)
    {
        if(b&1) ans=(ans*a)%mod1;
        b/=2;
        a=(a*a)%mod1;
    }
    return  ans;
}
int main()
{
    long long n,f1,f2,f3,c;
    long long cex,f1ex,f2ex,f3ex;
    cin>>n>>f1>>f2>>f3>>c;
    n-=3;
    node tmp;
    memset(tmp.a,0,sizeof(tmp.a));
    tmp.a[0][0]=1;
    tmp.a[0][1]=1;
    tmp.a[0][2]=1;
    tmp.a[0][3]=2;
    tmp.a[0][4]=-6;
    tmp.a[1][0]=1;
    tmp.a[2][1]=1;
    tmp.a[3][3]=1;
    tmp.a[3][4]=1;
    tmp.a[4][4]=1;
    node ans=power(tmp,n);
    cex=(ans.a[0][3]*4+ans.a[0][4])%mod;
    memset(tmp.a,0,sizeof(tmp.a));
    tmp.a[0][0]=1;
    tmp.a[0][1]=1;
    tmp.a[0][2]=1;
    tmp.a[1][0]=1;
    tmp.a[2][1]=1;
    ans=power(tmp,n);
    f1ex=(ans.a[0][2])%mod;
    f2ex=(ans.a[0][1])%mod;
    f3ex=(ans.a[0][0])%mod;
    long long ans1;
    long long num;
   // cout<<f1ex<<" "<<f2ex<<" "<<f3ex<<endl;
    ans1=quick_pow(c,cex)%mod1;
    ans1=ans1*quick_pow(f1,f1ex)%mod1;
    ans1=ans1*quick_pow(f2,f2ex)%mod1;
    ans1=ans1*quick_pow(f3,f3ex)%mod1;
    printf("%lld
",ans1);
}
原文地址:https://www.cnblogs.com/caowenbo/p/11852249.html