CF1182E 题解
前言
zlt 推荐矩阵加速题目。其实很不算难啊,不就是模拟吗。
思路
首先乘法是不能用矩阵加速直接维护的,考虑答案为
这些都是可以转移的。
对于
矩阵转移:
对于
矩阵转移:
对于
仅仅是初始化不同。
三者对应的指数就是第
最后再上快速幂即可求出。
代码
不喜欢用重载(次次考场都不会写重载格式),所以代码看起来会很长。
代码其实不用放的,抄一遍上面的矩阵即可。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int mod = 1e9 + 7;
typedef long long ll;
namespace martix_3 { //矩阵快速幂,懂的直接忽略即可
void mul(int ANS[][3], int x[][3], int y[][3])
{
int ans[3][3] = {};
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
for (int k = 0; k < 3; k++)
ans[i][j] = (ans[i][j] + 1ll * x[i][k] * y[k][j]) % (mod - 1);
memcpy(ANS, ans, sizeof ans);
}
void ksm(int f[][3], int a[][3], ll y)
{
while (y)
{
if (y & 1) mul(f, f, a);
mul(a, a, a);
y >>= 1;
}
}
};
namespace martix_5 { //矩阵快速幂,懂的直接忽略即可
void mul(int ANS[][5], int x[][5], int y[][5])
{
int ans[5][5] = {};
for (int i = 0; i < 5; i++)
for (int j = 0; j < 5; j++)
for (int k = 0; k < 5; k++)
ans[i][j] = (ans[i][j] + 1ll * x[i][k] * y[k][j]) % (mod - 1);
memcpy(ANS, ans, sizeof ans);
}
void ksm(int f[][5], int a[][5], ll y)
{
while (y)
{
if (y & 1) mul(f, f, a);
mul(a, a, a);
y >>= 1;
}
}
};
int qpow(int x, int y) //快速幂,懂的直接忽略即可
{
int ans = 1;
while (y)
{
if (y & 1) ans = (1ll * ans * x) % mod;
x = (1ll * x * x) % mod;
y >>= 1;
}
return ans;
}
int main()
{
ll n; int f1, f2, f3, c;
cin >> n >> f1 >> f2 >> f3 >> c;
int getc_f[5][5] = {0, 0, 0, 0, 1}; //i=3,算c
int getc_a[5][5] = {
0, 0, 1, 0, 0,
1, 0, 1, 0, 0,
0, 1, 1, 0, 0,
0, 0, 1, 1, 0,
0, 0, 2, 2, 1
};
martix_5::ksm(getc_f, getc_a, n - 3);
int c_k = getc_f[0][2];
int getf1_f[3][3] = {1, 0, 0}; //i=3,算f1
int getf1_a[3][3] = {
0, 0, 1,
1, 0, 1,
0, 1, 1
};
martix_3::ksm(getf1_f, getf1_a, n - 3);
int f1_k = getf1_f[0][2];
int getf2_f[3][3] = {0, 1, 0}; //i=3,算f2
int getf2_a[3][3] = {
0, 0, 1,
1, 0, 1,
0, 1, 1
};
martix_3::ksm(getf2_f, getf2_a, n - 3);
int f2_k = getf2_f[0][2];
int getf3_f[3][3] = {0, 0, 1}; //i=3,算f3
int getf3_a[3][3] = {
0, 0, 1,
1, 0, 1,
0, 1, 1
};
martix_3::ksm(getf3_f, getf3_a, n - 3);
int f3_k = getf3_f[0][2];
//printf("f_n = c^%d * f1^%d * f2^%d * f3^%d\n", c_k, f1_k, f2_k, f3_k);
int ans = 1;
ans = 1ll * ans * qpow(c, c_k) % mod;
ans = 1ll * ans * qpow(f1, f1_k) % mod;
ans = 1ll * ans * qpow(f2, f2_k) % mod;
ans = 1ll * ans * qpow(f3, f3_k) % mod;
cout << ans;
return 0;
}
希望能帮助到大家!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】