传送门

题目

\[\begin{aligned}
&f_n=c^{2*n-6}f_{n-1}f_{n-2}f_{n-3}&\\
\end{aligned}
\]

思路

我们通过迭代发现\(f_n\)其实就是由\(c^{t_1},f_1^{t_2},f_2^{t_3},f_3^{t_4}\)相乘得到,因此我们可以分别用矩阵快速幂求出\(t_1,t_2,t_3,t_4\),最后用快速幂求得答案。

对于\(n<=3\)的我们直接输出即可,\(n>3\)的我们先将\(n\)减去\(3\),然后进行求解。

对\(f_1,f_2,f_3\)的指数,我们可以推出\(x_n=x_{n-1}+x_{n-2}+x_{n-3}\):

\[\begin{aligned}
(x_n&&x_{n-1}&&x_{n-2})=(x_{n-1}&&x_{n-2}&&x_{n-3})
\left[
\begin{matrix}
1 & 1 & 0\\
1 & 0 & 1\\
1 & 0 & 0\\
\end{matrix}
\right]
\end{aligned}
\]

对\(c\)的指数,我们可以推出\(x_n=x_{n-1}+x_{n-2}+x_{n-3}+2n=x_{n-1}+x_{n-2}+x_{n-3}+2(n-1)+2\):

\[\begin{aligned}
(x_n&&x_{n-1}&&x_{n-2}&&n&&1)=(x_{n-1}&&x_{n-2}&&x_{n-3}&&n-1&&1)
\left[
\begin{matrix}
1 & 1 & 0 & 0 & 0\\
1 & 0 & 1 & 0 & 0\\
1 & 0 & 0 & 0 & 0\\
2 & 0 & 0 & 1 & 0\\
2 & 0 & 0 & 1 & 1\\
\end{matrix}
\right]
\end{aligned}
\]

注意,由于我们处理出来的\(x_1,x_2,x_3,x_4\)都是指数部分,这里如果膜\(1e9+7\)的话是不对的,我们还需要对其进行欧拉降幂。

代码实现

#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("D://code//in.txt","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-8;
const int mod = 1000000007;
const int maxn = 2e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL; int f[10], a[10][10]; void mulself(int a[10][10]) {
int c[10][10];
memset(c, 0, sizeof(c));
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3; j++) {
for(int k = 0; k < 3; k++) {
c[i][j] = (c[i][j] + (long long)a[i][k] * a[k][j] % (mod - 1)) % (mod - 1);
}
}
}
memcpy(a, c, sizeof(c));
} void mul(int f[10], int a[10][10]) {
int c[10];
memset(c, 0, sizeof(c));
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3; j++) {
c[i] = (c[i] + (long long)f[j] * a[j][i] % (mod - 1)) % (mod - 1);
}
}
memcpy(f, c, sizeof(c));
} void mulself1(int a[10][10]) {
int c[10][10];
memset(c, 0, sizeof(c));
for(int i = 0; i < 5; i++) {
for(int j = 0; j < 5; j++) {
for(int k = 0; k < 5; k++) {
c[i][j] = (c[i][j] + (long long)a[i][k] * a[k][j] % (mod - 1)) % (mod - 1);
}
}
}
memcpy(a, c, sizeof(c));
} void mul1(int f[10], int a[10][10]) {
int c[10];
memset(c, 0, sizeof(c));
for(int i = 0; i < 5; i++) {
for(int j = 0; j < 5; j++) {
c[i] = (c[i] + (long long)f[j] * a[j][i] % (mod - 1)) % (mod - 1);
}
}
memcpy(f, c, sizeof(c));
} int qpow(int x, int n) {
int res = 1;
while(n) {
if(n & 1) res = 1LL * res * x % mod;
x = 1LL * x * x % mod;
n >>= 1;
}
return res;
} LL n;
int f1, f2, f3, c; int main(){
scanf("%lld%d%d%d%d", &n, &f1, &f2, &f3, &c);
if(n == 1) return printf("%d\n", f1) * 0;
if(n == 2) return printf("%d\n", f2) * 0;
if(n == 3) return printf("%d\n", f3) * 0;
n -= 3;
LL ans = 1;
f[0] = 1, f[1] = 0, f[2] = 0;
a[0][0] = 1, a[0][1] = 1, a[0][2] = 0;
a[1][0] = 1, a[1][1] = 0, a[1][2] = 1;
a[2][0] = 1, a[2][1] = 0, a[2][2] = 0;
LL x = n;
while(x) {
if(x & 1) mul(f, a);
mulself(a);
x >>= 1;
}
ans = ans * qpow(f3, f[0]) % mod;
f[0] = 0, f[1] = 1, f[2] = 0;
a[0][0] = 1, a[0][1] = 1, a[0][2] = 0;
a[1][0] = 1, a[1][1] = 0, a[1][2] = 1;
a[2][0] = 1, a[2][1] = 0, a[2][2] = 0;
x = n;
while(x) {
if(x & 1) mul(f, a);
mulself(a);
x >>= 1;
}
ans = ans * qpow(f2, f[0]) % mod;
f[0] = 0, f[1] = 0, f[2] = 1;
a[0][0] = 1, a[0][1] = 1, a[0][2] = 0;
a[1][0] = 1, a[1][1] = 0, a[1][2] = 1;
a[2][0] = 1, a[2][1] = 0, a[2][2] = 0;
x = n;
while(x) {
if(x & 1) mul(f, a);
mulself(a);
x >>= 1;
}
ans = ans * qpow(f1, f[0]) % mod;
if(n == 1) f[0] = 2;
if(n == 2) f[0] = 6;
if(n == 3) f[0] = 14;
if(n > 3) {
n -= 3;
f[0] = 14, f[1] = 6, f[2] = 2, f[3] = 3, f[4] = 1;
memset(a, 0, sizeof(a));
a[0][0] = a[0][1] = 1;
a[1][0] = a[1][2] = 1;
a[2][0] = 1;
a[3][0] = 2, a[3][3] = 1;
a[4][0] = 2, a[4][3] = a[4][4] = 1;
while(n) {
if(n & 1) mul1(f, a);
mulself1(a);
n >>= 1;
}
}
ans = ans * qpow(c, f[0]) % mod;
printf("%lld\n", ans);
return 0;
}

Product Oriented Recurrence(Codeforces Round #566 (Div. 2)E+矩阵快速幂+欧拉降幂)的更多相关文章

  1. Codeforces Round #536 (Div. 2) F 矩阵快速幂 + bsgs(新坑) + exgcd(新坑) + 欧拉降幂

    https://codeforces.com/contest/1106/problem/F 题意 数列公式为\(f_i=(f^{b_1}_{i-1}*f^{b_2}_{i-2}*...*f^{b_k} ...

  2. Codeforces Round #307 (Div. 2) D 矩阵快速幂+快速幂

    D. GukiZ and Binary Operations time limit per test 1 second memory limit per test 256 megabytes inpu ...

  3. Codeforces Round #288 (Div. 2)D. Tanya and Password 欧拉通路

    D. Tanya and Password Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/508 ...

  4. Codeforces Round #565 (Div. 3)--D. Recover it!--思维+欧拉筛

    D. Recover it! Authors guessed an array aa consisting of nn integers; each integer is not less than ...

  5. Codeforces Round #566 (Div. 2)

    Codeforces Round #566 (Div. 2) A Filling Shapes 给定一个 \(3\times n\) 的网格,问使用 这样的占三个格子图形填充满整个网格的方案数 如果 ...

  6. Codeforces Round #566 (Div. 2)题解

    时间\(9.05\)好评 A Filling Shapes 宽度为\(3\),不能横向填 考虑纵向填,长度为\(2\)为一块,填法有两种 如果长度为奇数则显然无解,否则\(2^{n/2}\) B Pl ...

  7. Codeforces Round #566 (Div. 2) C. Beautiful Lyrics

    链接: https://codeforces.com/contest/1182/problem/C 题意: You are given n words, each of which consists ...

  8. Codeforces Round #566 (Div. 2) B. Plus from Picture

    链接: https://codeforces.com/contest/1182/problem/B 题意: You have a given picture with size w×h. Determ ...

  9. Codeforces Round #566 (Div. 2) A. Filling Shapes

    链接: https://codeforces.com/contest/1182/problem/A 题意: You have a given integer n. Find the number of ...

随机推荐

  1. traefik安装

    注意这篇文档有个错误,需要改正一下: 1.nginx1-7.yaml nginx1-8.yaml traefik.yaml 这三个文件里面的80端口需要改成8080端口,否则报错,其他的文件不变. 2 ...

  2. Java中常量以及常量池

    1.举例说明 变量 常量 字面量 int a=10; float b=1.234f; String c="abc"; final long d=10L; a,b,c为变量,d为常量 ...

  3. 自动问答最新研究成果展示(SQuAD)

    地址:https://rajpurkar.github.io/SQuAD-explorer/ Stanford Question Answering Dataset (SQuAD) is a read ...

  4. Redis Sentinel分布式集群

    helm部署Redis哨兵分布式集群 Redis Sentinel集群 介绍 Redis Sentinel集群是由若干Sentinel节点组成的分布式集群,可以实现故障发现.故障自动转移.配置中心和客 ...

  5. 【剑指offer】对称的二叉树

    题目描述 请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的. 分析:从上到下直接遍历,利用栈或者队列暂存结点,注意结点的存和取都是成对的 c ...

  6. JVM内存调优原则及几种JVM内存调优方法

      转载,如需帮助,请联系wlgchun@163.com https://blog.csdn.net/LeegooWang/article/details/88696195 如何对JVM进行内存调优? ...

  7. sql语句修改数据库字段的长度

    修改字段的长度 alter table [OtpimizeRoute_Test].[dbo].[T_QueueFile] alter column ListFileName nvarchar()

  8. 关于nslookup以及dig命令的研究报告

    我们在日常上网时都是用域名访问网路,如www.baidu.com,而在实际寻址过程中,是使用IP地址,如180.101.49.11,域名到IP地址的解析是通过DNS服务器来实现的,系统中我们可以用一些 ...

  9. golang http及其他标准库

  10. IDEA debug断点调试技巧

    Debug用来追踪代码的运行流程,通常在程序运行过程中出现异常,启用Debug模式可以分析定位异常发生的位置,以及在运行过程中参数的变化.通常我们也可以启用Debug模式来跟踪代码的运行流程去学习三方 ...