图灵杯-第四届“图灵杯”NEUQ-ACM 程序设计竞赛-F-一道简单的递推题
来源:互联网 发布:防蓝光软件有用吗 编辑:程序博客网 时间:2024/06/05 03:49
ACM模版
描述
题解
典型的矩阵快速幂问题,官方题解说需要用到滚动优化,是为了减少拷贝的次数……这里可以使用引用来减少拷贝,并且注意 long long,最开始输错了 0,不按套路出牌,竟然不是九个零,是十个!!!这里提供两个代码,都是矩阵快速幂,模版不同而已~~~
做这个题也让我发现了自己的一个知识漏洞,对引用认识不到位,同时也发现了自己模版中的缺陷,今天好好改了改,希望可以进一步完善她!
代码
One:
//AC 代码#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#define mod(x) ((x) % MOD)using namespace std;typedef long long ll;/* * 矩阵快速幂 n*n矩阵的x次幂 */const int MAXN = 111;const int MOD = 1e9 + 7;int n;struct mat{ int m[MAXN][MAXN]; // 矩阵乘法 mat operator * (mat &b) const { mat ret; memset(ret.m, 0, sizeof(ret.m)); for (int k = 1; k <= n; k++) { for (int i = 1; i <= n; i++) { if (m[i][k]) { for (int j = 1; j <= n; j++) { ret.m[i][j] = mod(ret.m[i][j] + (ll)m[i][k] * b.m[k][j]); } } } } return ret; } void init_unit() { for (int i = 1; i <= n; i++) { m[i][i] = 1; } } mat operator ^ (ll p) const { mat ret; ret.init_unit(); mat a; memcpy(a.m, m, sizeof(m)); while (p) { if (p & 1) { ret = ret * a; } p >>= 1; a = a * a; } return ret; }} tmp; // 单元矩阵ll k, F[MAXN];int main(){ scanf("%d%lld", &n, &k); for (int i = 1; i <= n; i++) { scanf("%lld", F + i); } for (int i = 1; i < n; i++) { tmp.m[i][i + 1] = 1; } for (int j = 1; j <= n; j++) { scanf("%d", &tmp.m[n][n - j + 1]); } tmp = tmp ^ (k - n); long long ans = 0; for (int j = 1; j <= n; j++) { ans = mod(ans + tmp.m[n][j] * F[j]); } printf("%lld\n", ans); return 0;}
Two:
// AC 代码#include <iostream>#include <cstdio>#include <cstring>#define mod(x) ((x) % MOD)using namespace std;typedef long long ll;/* * 矩阵快速幂 n * n矩阵的x次幂 */const int MAXN = 111;const int MOD = 1e9 + 7;int n;struct mat{ int m[MAXN][MAXN];} unit, a; // 单元矩阵// 矩阵乘法mat operator * (mat a, mat &b){ mat ret; memset(ret.m, 0, sizeof(ret.m)); for (int k = 0; k < n; k++) { for (int i = 0; i < n; i++) { if (a.m[i][k]) { for (int j = 0; j < n; j++) { ret.m[i][j] = mod(ret.m[i][j] + (ll)a.m[i][k] * b.m[k][j]); } } } } return ret;}void init_unit(){ for (int i = 0; i < MAXN; i++) { unit.m[i][i] = 1; } return ;}mat pow_mat(mat &a, ll n){ mat ret = unit; while (n) { if (n & 1) { ret = ret * a; } n >>= 1; a = a * a; } return ret;}ll k, F[MAXN];int main(){ init_unit(); scanf("%d%lld", &n, &k); for (int i = 0; i < n; i++) { scanf("%lld", F + i); } for (int i = 0; i < n - 1; i++) { a.m[i][i + 1] = 1; } for (int j = 0; j < n; j++) { scanf("%d", &a.m[n - 1][n - j - 1]); } if (k <= n) { printf("%lld\n", mod(F[k - 1])); return 0; } a = pow_mat(a, k - n); // a矩阵的x次幂 long long ans = 0; for (int j = 0; j < n; j++) { ans = mod(ans + a.m[n - 1][j] * F[j]); } printf("%lld\n", ans); return 0;}
阅读全文
0 0
- 图灵杯-第四届“图灵杯”NEUQ-ACM 程序设计竞赛-F-一道简单的递推题
- 图灵杯-第四届“图灵杯”NEUQ-ACM 程序设计竞赛-J-简单的变位词
- 图灵杯-第四届“图灵杯”NEUQ-ACM 程序设计竞赛-E-简单的RMQ
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛 E: 简单的RMQ【线段树】
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛总结 【8/10】
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛部分题解
- 第四届“图灵杯”NEUQ-ACM 程序设计竞赛(团队赛)
- 图灵杯-第四届“图灵杯”NEUQ-ACM 程序设计竞赛-C-来简单地数个数
- 图灵杯-第四届“图灵杯”NEUQ-ACM 程序设计竞赛-D-简单图形输出
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛 C: 来简单地数个数【Java大数】
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛(团队赛)-网络同步赛F(矩阵快速幂)
- 图灵杯-第四届“图灵杯”NEUQ-ACM 程序设计竞赛-A-谷神的赌博游戏
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛 A: 谷神的游戏【思维+组合数学】
- 图灵杯-第四届“图灵杯”NEUQ-ACM 程序设计竞赛-G-那么大奶牛之神
- **第四届“图灵杯”NEUQ-ACM程序设计竞赛(个人赛)C粉丝与汉诺塔
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛(团队赛)-网络同步赛A(组合数学)
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛(团队赛)-网络同步赛B(排序)
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛(团队赛)-网络同步赛E(线段树)
- java利用Comparator与Collections.sort对List排序
- HashMap实现原理分析
- html+css简单下拉菜单制作
- 链表是否有环的两种判断方法
- 真Unity3d_自带默认寻路插件NavMesh入门完全解析
- 图灵杯-第四届“图灵杯”NEUQ-ACM 程序设计竞赛-F-一道简单的递推题
- python环境搭建-包管理工具homebrew
- java 字符串替换效率
- mybatis-映射器-resultMap结果集映射3collection一对多级联&鉴别器
- Linux 学习笔记5.7
- 2.函数
- form表单提交点击按钮提交form表单
- VS2015 vs2017 密钥
- 通俗易懂的 “数据库范式(1NF 2NF 3NF BCNF)详解”