题目链接：

https://codeforces.com/contest/1182/problem/E

具体思路：

f2，f3同理。

(g[i],g[i-1],g[i-2])=(g[i-1],g[i-2],g[i-3])*

[1 1 0

1 0 1

1 0 0   ].

(f[i],f[i-1],f[i-2],g[i-3],i,1) = (f[i-1],f[i-2],f[i-3],i-1,1)*

[ 1 1 0 0 0

1 0 1 0 0

1 0 0 0 0

2 0 0 1 0

-4 0 0 1 1

]

AC代码：

1 #include<bits/stdc++.h>
2 using namespace std;
3 const int maxn = 2e6+20;
4 # define ll long long
5 # define inf 0x3f3f3f3f
6 const ll mod = 1e9+6;
7 ll MD=mod+1;
8 ll phi(ll x)
9 {
10     ll res=x,a=x;
11     for(ll i=2; i*i<=x; i++)
12     {
13         if(a%i==0)
14         {
15             res=res/i*(i-1ll);
16             while(a%i==0)
17                 a/=i;
18         }
19     }
20     if(a>1ll)
21         res=res/a*(a-1ll);
22     return res;
23 }
24 struct Matrix_First
25 {
26     ll a[5][5];
27     Matrix_First operator *(Matrix_First b)
28     {
29         Matrix_First tmp;
30         for(int i=1; i<=3; i++)
31         {
32             for(int j=1; j<=3; j++)
33             {
34                 tmp.a[i][j]=0;
35                 for(int k=1; k<=3; k++)
36                 {
37                     tmp.a[i][j]=(tmp.a[i][j]+a[i][k]*b.a[k][j]%mod)%mod;
38                     while(tmp.a[i][j]<0)
39                         tmp.a[i][j]+=mod;// 这是求指数的过程
40                     tmp.a[i][j]%=mod;
41                 }
42             }
43         }
44         return tmp;
45     }
46 } g1,g2,g3;
47 struct Matrix_Second
48 {
49     ll a[6][6];
50     Matrix_Second operator *(Matrix_Second b)
51     {
52         Matrix_Second tmp;
53         for(int i=1; i<=5; i++)
54         {
55             for(int j=1; j<=5; j++)
56             {
57                 tmp.a[i][j]=0;
58                 for(int k=1; k<=5; k++)
59                 {
60                     tmp.a[i][j]=(tmp.a[i][j]+a[i][k]*b.a[k][j]%mod)%mod;
61                     while(tmp.a[i][j]<mod)
62                         tmp.a[i][j]+=mod;
63                     tmp.a[i][j]%=mod;
64                 }
65             }
66         }
67         return tmp;
68     }
69 } f;
70
71 Matrix_First qsm_First(Matrix_First t1,ll t2)
72 {
73     Matrix_First  ans=t1;
74     t2--;
75     while(t2)
76     {
77         if(t2&1)
78             ans=ans*t1;
79         t1=t1*t1;
80         t2>>=1;
81     }
82     return ans;
83 }
84
85 Matrix_Second qsm_Second(Matrix_Second t1,ll t2)
86 {
87     Matrix_Second  ans=t1;
88     t2--;
89     while(t2)
90     {
91         if(t2&1)
92             ans=ans*t1;
93         t1=t1*t1;
94         t2>>=1;
95     }
96     return ans;
97 }
98
99 ll qsm(ll t1,ll t2)
100 {
101     ll ans=1ll;
102     while(t2)
103     {
104         if(t2&1)
105             ans=ans*t1%MD;
106         t1=t1*t1%MD;
107         t2>>=1;
108     }
109     return ans;
110 }
111 int main()
112 {
113     ll n,f1,f2,f3,c;
114     scanf("%lld %lld %lld %lld %lld",&n,&f1,&f2,&f3,&c);
115     g1.a[1][1]=1;g1.a[1][2]=1;g1.a[1][3]=0;
116     g1.a[2][1]=1;g1.a[2][2]=0;g1.a[2][3]=1;
117     g1.a[3][1]=1;g1.a[3][2]=0;g1.a[3][3]=0;
118
119     g2.a[1][1]=1;g2.a[1][2]=1;g2.a[1][3]=0;
120     g2.a[2][1]=1;g2.a[2][2]=0;g2.a[2][3]=1;
121     g2.a[3][1]=1;g2.a[3][2]=0;g2.a[3][3]=0;
122
123     g3.a[1][1]=1;g3.a[1][2]=1;g3.a[1][3]=0;
124     g3.a[2][1]=1;g3.a[2][2]=0;g3.a[2][3]=1;
125     g3.a[3][1]=1;g3.a[3][2]=0;g3.a[3][3]=0;
126     g1=qsm_First(g1,(n-3ll));
127     g2=qsm_First(g2,(n-3ll));
128     g3=qsm_First(g3,(n-3ll));
129
130     ll num_1=g1.a[3][1];
131     ll num_2=g2.a[2][1];
132     ll num_3=g3.a[1][1];
133     f.a[1][1]=1;f.a[1][2]=1;f.a[1][3]=0;f.a[1][4]=0;f.a[1][5]=0;
134     f.a[2][1]=1;f.a[2][2]=0;f.a[2][3]=1;f.a[2][4]=0;f.a[2][5]=0;
135     f.a[3][1]=1;f.a[3][2]=0;f.a[3][3]=0;f.a[3][4]=0;f.a[3][5]=0;
136     f.a[4][1]=2;f.a[4][2]=0;f.a[4][3]=0;f.a[4][4]=1;f.a[4][5]=0;
137     f.a[5][1]=-4;f.a[5][2]=0;f.a[5][3]=0;f.a[5][4]=1;f.a[5][5]=1;
138     f=qsm_Second(f,n-3ll);
139     ll num_c=(3ll*f.a[4][1]+f.a[5][1]);
140     while(num_c<0)
141         num_c+=mod;
142     num_c%=mod;
143
144     ll ans=qsm(f1,num_1)%MD*qsm(f2,num_2)%MD;
145    // cout<<ans<<endl;
146     while(ans<0)
147         ans+=MD;
148     ans%=MD;
149     ans=ans*qsm(f3,num_3)%MD;
150    // cout<<ans<<endl;
151     while(ans<0)
152         ans+=MD;
153     ans%=MD;
154     ans=ans*qsm(c,num_c)%MD;
155    // cout<<ans<<endl;
156     while(ans<0)
157         ans+=MD;
158     ans%=MD;
159     printf("%lld\n",ans);
160     return 0;
161 }