const int N = 1e4+5;
void mul(ll c[][3], ll a[][3], ll b[][3])
{
ll tmp[3][3] = {0};
f(i, 0, 2)
f(j, 0, 2)
f(k, 0, 2)tmp[i][j] = (tmp[i][j] + a[i][k] * b[k][j]) % (mod-1);
memcpy(c, tmp, sizeof tmp);
}
void jzksm(ll a[][3],ll n)
{
ll tmp[3][3] = { 0 };
f(i, 0, 2)tmp[i][i] = 1;
while (n)
{
if (n & 1)mul(tmp, tmp, a);
mul(a, a, a);
n >>= 1;
}
memcpy(a, tmp, sizeof tmp);
}
void mul2(ll c[][5], ll a[][5], ll b[][5])
{
ll tmp[5][5] = { 0 };
f(i, 0, 4)
f(j, 0, 4)
f(k, 0, 4)tmp[i][j] = (tmp[i][j] + a[i][k] * b[k][j]) % (mod - 1);
memcpy(c, tmp, sizeof tmp);
}
void jzksm2(ll a[][5], ll n)
{
ll tmp[5][5] = { 0 };
f(i, 0, 5)tmp[i][i] = 1;
while (n)
{
if (n & 1)mul2(tmp, tmp, a);
mul2(a, a, a);
n >>= 1;
}
memcpy(a, tmp, sizeof tmp);
}
int main()//递推式中出现乘法考虑转化成幂的加法再用矩阵加速求解
{
//freopen("in.txt", "r", stdin);
ll n, f1, f2, f3,k;
cin >> n >> f1 >> f2 >> f3 >> k;
ll a[3][3] = {0,0,1};
ll b[3][3] = { 0,1,0 };
ll c[3][3] = { 1,0,0 };
ll f[3][3] = { 1,1,0,
1,0,1,
1,0,0 };
jzksm(f, n-3);
mul(a, a, f);
ll ff[3][3]= { 1,1,0,
1,0,1,
1,0,0 };
jzksm(ff, n - 3);
mul(b, b, ff);
ll fff[3][3] = { 1,1,0,
1,0,1,
1,0,0 };
jzksm(fff, n - 3);
mul(c, c, fff);
ll ffff[5][5] = { 0,0,1,0,0,
1,0,1,0,0,
0,1,1,0,0,
0,0,1,1,0,
0,0,0,1,1 };
ll base[5][5] = { 0,0,0,2,2 };
jzksm2(ffff, n - 3);
mul2(base, base, ffff);
ll ans = quickmod(k, base[0][2], mod);
ans = ans * quickmod(f1, a[0][0], mod) % mod;
ans = ans * quickmod(f2, b[0][0], mod) % mod;
ans = ans * quickmod(f3, c[0][0], mod) % mod;
cout << ans << endl;
return 0;
}
E. Product Oriented Recurrence(乘法递推转化成幂的加法)
最新推荐文章于 2021-03-02 19:40:37 发布