题意:设f(n) = c ^ (2n - 6) * f(n - 1) * f(n - 2) * f(n - 3), 问第n项是多少?

思路:官方题解:我们先转化一下,令g(x) =  c ^ x * f(x), 那么原式转化为了g(x) = g(x - 1) * g(x - 2) * g(x - 3)。之后我们可以考虑把f(1), f(2), f(3)和c的质因子找出来,枚举质因子对答案的贡献。我们发现,如果是质因子的数目的话,乘法就变成了加法(相当于统计质因子的指数),这样就可以用矩阵乘法优化了。注意,矩阵转移的时候,模数是1e9 + 6,因为转移的时候是指数(欧拉定理)。其实基于这种想法,我们可以不用处理质因子,直接计算g(1), g(2),g(3)对答案的贡献。

代码:

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const LL mod = 1e9 + 7;
const LL mod1 = 1e9 + 6;
map<LL, LL> mp[4];
set<LL> s;
set<LL>::iterator it;
struct Matrix {
LL a[3][3]; void init(LL num = 0) {
memset(a, 0, sizeof(a));
for (int i = 0; i < 3; i++)
a[i][i] = num;
} Matrix operator * (const Matrix& now) const {
Matrix res;
res.init();
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
for (int k = 0; k < 3; k++)
res.a[i][j] = (res.a[i][j] + (a[i][k] * now.a[k][j]) % mod1) % mod1;
return res;
} Matrix operator ^ (const LL num) const {
Matrix ans, x = *this;
ans.init(1);
LL now = num;
for (; now; now >>= 1) {
if(now & 1) ans = ans * x;
x = x * x;
}
return ans;
} void print() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printf("%lld ", a[i][j]);
}
printf("\n");
} }
};
void div(LL num, int pos) {
for (LL i = 2; i * i <= num; i++) {
if(num % i == 0) {
s.insert(i);
while(num % i == 0) {
mp[pos][i]++;
num /= i;
}
}
}
if(num > 1) {
s.insert(num);
mp[pos][num]++;
}
}
LL qpow(LL x, LL y) {
LL ans = 1;
for (; y; y >>= 1ll) {
if(y & 1ll) ans = (ans * x) % mod;
x = (x * x) % mod;
}
return ans;
}
LL a[4];
int main() {
LL n;
scanf("%lld", &n);
for (int i = 0; i < 4; i++) {
scanf("%lld", &a[i]);
div(a[i], i);
}
Matrix x, y, x1;
x.init();
x.a[0][2] = x.a[1][2] = x.a[2][2] = x.a[2][1] = x.a[1][0] = 1;
x = x ^ (n - 1);
LL ans = 1;
for (it = s.begin(); it != s.end(); it++) {
y.init();
for (int i = 0; i < 3; i++) {
y.a[0][i] = mp[i][*it];
}
for (int i = 0; i < 3; i++)
y.a[0][i] = (y.a[0][i] + ((LL)(i + 1) * mp[3][*it] % mod)) % mod;
y = y * x;
ans = (ans * qpow(*it, y.a[0][0]) % mod) % mod;
}
ans = ans * qpow(qpow(a[3], mod - 2), n) % mod;
printf("%lld\n", ans);
}

  

codeforces 1182E Product Oriented Recurrence 矩阵快速幂的更多相关文章

  1. CodeForces 1182E Product Oriented Recurrence

    题意 给定五个整数 \(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\). ...

  2. Educational Codeforces Round 60 D dp + 矩阵快速幂

    https://codeforces.com/contest/1117/problem/D 题意 有n个特殊宝石(n<=1e18),每个特殊宝石可以分解成m个普通宝石(m<=100),问组 ...

  3. Codeforces 1067D - Computer Game(矩阵快速幂+斜率优化)

    Codeforces 题面传送门 & 洛谷题面传送门 好题. 首先显然我们如果在某一次游戏中升级,那么在接下来的游戏中我们一定会一直打 \(b_jp_j\) 最大的游戏 \(j\),因为这样得 ...

  4. codeforces 678D Iterated Linear Function 矩阵快速幂

    矩阵快速幂的题要多做 由题可得 g[n]=A*g[n-1]+B 所以构造矩阵  { g[n] }    =  {A   B}  * { g[n-1]} {   1   }         {0   1 ...

  5. Educational Codeforces Round 14E. Xor-sequences(矩阵快速幂)

    传送门 题意 给定序列,从序列中选择k(1≤k≤1e18)个数(可以重复选择),使得得到的排列满足\(x_i与x_{i+1}\)异或的二进制表示中1的个数是3的倍数.问长度为k的满足条件的序列有多少种 ...

  6. Codeforces 185A Plant( 递推关系 + 矩阵快速幂 )

    链接:传送门 题意:输出第 n 年向上小三角形的个数 % 10^9 + 7 思路: 设 Fn 为第 n 年向上小三角形的个数,经过分析可以得到 Fn = 3 * Fn-1 + ( 4^(n-1) - ...

  7. 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} \] 思路 我们通过迭代发 ...

  8. Educational Codeforces Round 13 D. Iterated Linear Function (矩阵快速幂)

    题目链接:http://codeforces.com/problemset/problem/678/D 简单的矩阵快速幂模版题 矩阵是这样的: #include <bits/stdc++.h&g ...

  9. Codeforces Round #257 (Div. 2) B. Jzzhu and Sequences (矩阵快速幂)

    题目链接:http://codeforces.com/problemset/problem/450/B 题意很好懂,矩阵快速幂模版题. /* | 1, -1 | | fn | | 1, 0 | | f ...

随机推荐

  1. Thread类和Runable接口使用

    不废话,就一个类,直接拷贝代码执行 package com.jtfr.demo; /** * 主要:继承 Thread 类和 Runnable接口 * @author 陈康明 qq:112318152 ...

  2. PHP微信红包生成算法的程序源码(用抛物线的模型实现)

    代码如下: <?php /* * 红包生成随机算法 */ header("Content-type:text/html;charset=utf-8"); date_defau ...

  3. [REPRINT]MySQL Indexing Explained

    https://atech.blog/viaduct/mysql-indexes-primer What are Indexes? Every time your web application ru ...

  4. 【leetcode】316. Remove Duplicate Letters

    题目如下: Given a string which contains only lowercase letters, remove duplicate letters so that every l ...

  5. 【leetcode】435. Non-overlapping Intervals

    题目如下: Given a collection of intervals, find the minimum number of intervals you need to remove to ma ...

  6. openwrt增加密码及ssh的方法

    openwrt增加密码及ssh的方法 1.进入openwrt系统源码的顶层目录,然后执行 make menuconfig命令进入 Network--> SSH-->  <*>o ...

  7. 【Bootstrapt】offset、push、pull

    实现方式的区别: col-md-offset-*,是利用margin-left实现的,col-md-push-*/col-md-pull-*是利用相对定位实现的. 效果的区别: col-md-offs ...

  8. django 框架下的路由分发

  9. centos6 sersync2使用

    接收端rsyncd搭建 http://www.cnblogs.com/hanxiaohui/p/8675409.html 推送端sersync2使用 安装 源码包D:\share\src\sersyn ...

  10. webstorm 插件安装

    1.打勾的表示已经安装 2.没有安装的插件,可以在plugins搜索,在右边搜索结果里点install,然后重启webstorm 3.这里有常用插件 http://blog.csdn.net/xs20 ...