题意

给定五个整数 \(n,f_1,f_2,f_3,c\),其中数列 \(f\) 满足以下递推式:

\[f_x=c^{2x-6}f_{x-1}f_{x-2}f_{x-3}
\]

求 \(f_n\)。

\(\texttt{Data Range:}4\leq n\leq 10^{18},1\leq f_1,f_2,f_3,c\leq 10^9\)

题解

矩阵快速幂。

首先这个乘起来的东西显然没有什么方法去递推,然而从递推式中可以直接看出 \(f_n\) 是类似于 \(c^gf_1^{i}f_2^{j}f_3^{k}\) 的形式,所以考虑把每个次数算出来然后快速幂。

注意到这个次数很好算的。设 \(f_n\) 中 \(c\) 的次数为 \(g_n\),那么显然有递推式

\[g_n=2n-6+g_{n-1}+g_{n-2}+g_{n-3}=2(n-1)-4+g_{n-1}+g_{n-2}+g_{n-3}
\]

注意到这个东西是常见的非齐次线性递推模样,于是可以高高兴兴的走一波矩阵:

\[\begin{pmatrix}g_n\\g_{n-1}\\g_{n-2}\\n\\1\end{pmatrix}=\begin{pmatrix}1&1&1&2&-4\\1&0&0&0&0\\0&1&0&0&0\\0&0&0&1&1\\0&0&0&0&1\end{pmatrix}\begin{pmatrix}g_{n-1}\\g_{n-2}\\g_{n-3}\\n-1\\1\end{pmatrix}
\]

然后考虑递推 \(f_1,f_2,f_3\) 的次数。以 \(f_1\) 为例,设 \(f_n\) 中 \(f_1\) 的次数为 \(h_n\),那么有

\[h_n=h_{n-1}+h_{n-2}+h_{n-3}
\]

这个转移矩阵挺好写的,也就是:

\[\begin{pmatrix}h_n\\h_{n-1}\\h_{n-2}\end{pmatrix}=\begin{pmatrix}1&1&1\\1&0&0\\0&1&0\end{pmatrix}\begin{pmatrix}h_{n-1}\\h_{n-2}\\h_{n-3}\end{pmatrix}
\]

同时注意到 \(f_2\) 和 \(f_3\) 次数的递推式也是这个东西,只不过 \(h_1,h_2,h_3\) 不同而已,于是这个也可以递推出来了,然后就做完了。

代码

#include<bits/stdc++.h>
using namespace std;
typedef int ll;
typedef long long int li;
const ll MAXN=2e5+51,MOD=1e9+7;
struct Matrix{
ll num[6][6];
Matrix()
{
memset(num,0,sizeof(num));
}
inline ll* operator [](const ll &x)
{
return num[x];
}
inline const ll* operator [](const ll &x)const
{
return num[x];
}
};
Matrix mat,mat2,x,x2;
ll f1,f2,f3,c,res;
li n;
inline li read()
{
register li num=0,neg=1;
register char ch=getchar();
while(!isdigit(ch)&&ch!='-')
{
ch=getchar();
}
if(ch=='-')
{
neg=-1;
ch=getchar();
}
while(isdigit(ch))
{
num=(num<<3)+(num<<1)+(ch-'0');
ch=getchar();
}
return num*neg;
}
inline ll qpow(ll base,ll exponent)
{
ll res=1;
while(exponent)
{
if(exponent&1)
{
res=(li)res*base%MOD;
}
base=(li)base*base%MOD,exponent>>=1;
}
return res;
}
inline Matrix operator *(Matrix x,Matrix y)
{
Matrix res;
for(register int i=1;i<=5;i++)
{
for(register int j=1;j<=5;j++)
{
for(register int k=1;k<=5;k++)
{
res[i][j]=(res[i][j]+(li)x[i][k]*y[k][j]%(MOD-1))%(MOD-1);
}
}
}
return res;
}
inline Matrix qpow(Matrix base,li exponent)
{
Matrix res;
for(register int i=1;i<=5;i++)
{
res[i][i]=1;
}
while(exponent)
{
if(exponent&1)
{
res=res*base;
}
base=base*base,exponent>>=1;
}
return res;
}
int main()
{
n=read(),f1=read(),f2=read(),f3=read(),c=read(),res=1;
mat[1][1]=mat[2][1]=mat[3][1]=mat[1][2]=mat[2][3]=mat[4][4]=mat[5][4]=1;
mat[5][5]=x[1][5]=mat2[1][1]=1,mat[4][1]=2,mat[5][1]=MOD-5,x[1][4]=3;
mat2[2][1]=mat2[3][1]=mat2[1][2]=mat2[2][3]=x2[1][3]=1;
res=qpow(c,(x*qpow(mat,n-3))[1][1]);
res=(li)res*qpow(f1,(x2*qpow(mat2,n-3))[1][1])%MOD,x2[1][3]=0,x2[1][2]=1;
res=(li)res*qpow(f2,(x2*qpow(mat2,n-3))[1][1])%MOD,x2[1][2]=0,x2[1][1]=1;
res=(li)res*qpow(f3,(x2*qpow(mat2,n-3))[1][1])%MOD,printf("%d\n",res);
}

CodeForces 1182E Product Oriented Recurrence的更多相关文章

  1. codeforces 1182E Product Oriented Recurrence 矩阵快速幂

    题意:设f(n) = c ^ (2n - 6) * f(n - 1) * f(n - 2) * f(n - 3), 问第n项是多少? 思路:官方题解:我们先转化一下,令g(x) =  c ^ x * ...

  2. Product Oriented Recurrence(Codeforces Round #566 (Div. 2)E+矩阵快速幂+欧拉降幂)

    传送门 题目 \[ \begin{aligned} &f_n=c^{2*n-6}f_{n-1}f_{n-2}f_{n-3}&\\ \end{aligned} \] 思路 我们通过迭代发 ...

  3. CF1182E Product Oriented Recurrence

    思路: fn = can * f1xn * f2yn * f3zn, 首先dp计算指数部分an = an-1 + an-2 + an-3 + 2 * n - 6, 而an-1 = an-2 + an- ...

  4. cf 1182 E - Product Oriented Recurrence

    当时脑残了, 不会写矩阵快速幂中更改的系数, 其实把他扔到矩阵里同时递推就好了 #include<cstdio> #include<algorithm> #include< ...

  5. codeforces Unusual Product

    题意:给你n*n的矩阵,里面是1或0,然后q次询问,如果操作数为1,那么就把x行的数0变成1,1变成0:如果操作数为2,那么在x列上的数0变成1,1变成0:如果是3,输出: 思路:在求的时候,对角线上 ...

  6. Codeforces 631E Product Sum 斜率优化

    我们先把问题分成两部分, 一部分是把元素往前移, 另一部分是把元素往后移.对于一个 i 后的一个位置, 我们考虑前面哪个移到这里来最优. 我们设最优值为val,   val = max(a[ j ] ...

  7. @codeforces - 631E@ Product Sum

    目录 @desription@ @solution@ @accepted code@ @details@ @desription@ 给定一个序列 a,定义它的权值 \(c = \sum_{i=1}^{ ...

  8. Codeforces 1294C - Product of Three Numbers

    题目大意: 给定一个n,问是否存在3个互不相同的,大于等于2的整数,满足a*b*c=n 解题思路: 可以把abc其中任意两个看作一个整体,例如a*b=d,那么可以发现d*c=n 所以d和c是n的因子 ...

  9. Codeforces Round #566 (Div. 2)

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

随机推荐

  1. vsCode 搭建Java开发环境

    1.安装扩展 Java Extension Pack Spring Boot Extension Pack 2.配置Maven 打开设置 搜索maven 找到并打开  在 settings.json ...

  2. Python新手入门基础

    认识 Python 人生苦短,我用 Python -- Life is short, you need Python 目标 Python 的起源 为什么要用 Python? Python 的特点 Py ...

  3. 针对Linux上Java程式运行脚本的Log信息记录操作人员记录以及成功运行判断

    简介与优点 使用该教程,能直观地看到java启动脚本是否启动/关闭成功 能让自己的启动时间日期都记录在Log中 能记录有哪些人登陆了该服务器操作了启动关闭脚本(记录IP地址) 使用说明 在原有的启动和 ...

  4. 这里有一份Java程序员的珍藏书单,请您注意查收

    前言 不要因为迷茫,而停止了脚下前进的路.给大家推荐一份Java程序员必看的书单,豆瓣评分都挺不错的,每一本都值得去读,都值得去收藏,加油呀 本文已经收录到github https://github. ...

  5. spark-1-架构设计&基本流程

    Spark运行架构包括: (1)集群资源管理器(Cluster Manager) (2)运行作业任务的工作节点(Worker Node) (3)每个应用的任务控制节点(Driver)和每个工作节点上负 ...

  6. jvm优化案例

    案例1 survivor区太小,每次Minor GC存活的对象进入老年代,导致老年代可用空间不足,经常发生FULL GC,导致系统变慢 案例问题描述 有一个数据计算系统,从mysql和其他数据源提取数 ...

  7. 获取豆瓣读书所有热门标签并保存到mongodb数据库

    目标url:https://book.douban.com/tag/?view=type&icn=index-sorttags-all 目的:抓取所有标签名称(tag_name),标签链接(t ...

  8. 028 01 Android 零基础入门 01 Java基础语法 03 Java运算符 08 逻辑“或”运算符

    028 01 Android 零基础入门 01 Java基础语法 03 Java运算符 08 逻辑"或"运算符 本文知识点:Java中的逻辑"或"运算符 逻辑& ...

  9. 《To C产品经理进阶》

    我所说的,都是错的. To C产品设计和To B产品设计对一个优秀的产品经理的洞察能力.架构能力有共通的要求. 实际产品设计过程中,To C产品往往是从商业思维思考,侧重用户研究,思考用户心智,由产品 ...

  10. Dockerize ASP。净样板项目

    Get the source code from the Github repository. 介绍 在这篇文章中,我将一步步地向你展示如何在Docker上运行ABP模块零核心模板.然后,我们将讨论其 ...