codeforces 1182F 矩阵快速幂
Posted pkgunboat
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces 1182F 矩阵快速幂相关的知识,希望对你有一定的参考价值。
题意:设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 1182F 矩阵快速幂的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #257 (Div. 2) B. Jzzhu and Sequences (矩阵快速幂)
Codeforces 450B div.2 Jzzhu and Sequences 矩阵快速幂or规律
Codeforces1106F BSGS矩阵快速幂exgcd
Educational Codeforces Round 60 (Rated for Div. 2) D. Magic Gems(矩阵快速幂)