hdu5171 GTY's birthday gift(BestCoder Round #29 1002)
来源:互联网 发布:校园网络建设招标书 编辑:程序博客网 时间:2024/05/23 01:19
题意: 递推数列求和
给一个有
符号定义
方法一: 利用周期性
因为是对MOD=10000007取余,所以
对应代码中的第44~52行
c的算法:利用di 的递推式计算,当出现di=a且di−1=b 时,此时的i就是c的值.
用s1存储一段周期的元素和.
这段代码结束后,有两种情况:①循环正常结束,表示k比较小,还不用算出c,已经得到答案了.②循环被break,表示此时的i即为c的值.
两种情况可以用第51~59行的代码统一处理.
第5~14行是读入外挂,第27~37行是在数组中找出最大的两个数的一种方法.
#include <algorithm> #include <iostream>using namespace std; #define ISDIG ((c=getchar())>='0'&&c<='9')template <typename T>inline int read(T& x) { int c, sign = 1; x = 0; while (!(ISDIG || c == '-')) if (c == EOF) return c; if (c == '-') sign = -1; else x = x*10 + c - '0'; while (ISDIG) x = x*10 + c - '0'; x *= sign; return 1;}const int MOD = 10000007;int d[MOD + 10];int main() { int n, k, a, b; int t, i; // 临时变量、计数器 while (cin >> n >> k) { read(a); read(b); int s = a + b; for (i = 2; i < n; i++) { //{找出初始S中最大的两个数a,b read(t); if (t > a) { if (t > b) { if (a < b) a = t; else b = t; } else a = t; } else if (t > b) b = t; //} s = (s + t) % MOD; } if (b > a) swap(a , b); // 假设a>=b d[0] = a; d[1] = a + b; //{计算出周期c和这段周期的元素和s1 int c, s1 = d[1]; for (i = 2; i <= k; i++) { d[i] = (d[i-1] + d[i-2]) % MOD; s1 = (d[i] + s1) % MOD; if (d[i] == a && d[i-1] == b) break; } c = i; //} do { s = (s + s1) % MOD; k -= c; } while (k > c); // 去掉完整的周期后,还有些残余的末尾项要加上 for (i = 1; i <= k; i++) s = (d[i] + s) % MOD; cout << s << "\n"; } return 0;}
注意也只有64MB的内存限制才可以用这个方法,因为32MB只能开辟800万大小的一个int数组╮(╯▽╰)╭.
方法二: 矩阵快速幂模
矩阵快速幂模的解法原理,我就不讲这么详细了.去年做过这道比较基础的矩阵快速幂模题:FOJ 1683 纪念SlingShot,那道题理解后,此类题型的基本思想就掌握了,这题难度差不多.
FOJ 1692 Key problem这篇博客讲了道更难的矩阵快速幂模题.
这题关键是推出如下的公式:
⎛⎝⎜100111110⎞⎠⎟k⎛⎝⎜S0ab⎞⎠⎟=⎛⎝⎜Skdkdk−1⎞⎠⎟
借着做这题的机会,开发个新的矩阵类.
#include <algorithm> #include <cstring> #include <iostream>using namespace std; #define ISDIG ((c=getchar())>='0'&&c<='9')template <typename T>inline int read(T& x) { int c, sign = 1; x = 0; while (!(ISDIG || c == '-')) if (c == EOF) return c; if (c == '-') sign = -1; else x = x*10 + c - '0'; while (ISDIG) x = x*10 + c - '0'; x *= sign; return 1;}/*矩阵类(用于快速幂模) 1、T是整型类型,N是方阵大小,MOD是取余的值 2、Eye是单位阵*/template <typename T, const int N, const int MOD>class Matrix { T val[N][N];public: Matrix() { memset(val, 0, sizeof(val)); } Matrix(T a[N][N]) { memcpy(val, a, sizeof(val)); } Matrix operator*(const Matrix& c) const { Matrix res; for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) for (int k = 0; k < N; ++k) { res.val[i][j] += val[i][k] * c.val[k][j]; //防止矩阵元素变为负数,若不需要,去掉"+MOD" res.val[i][j] = (res.val[i][j] + MOD) % MOD; } return res; } Matrix& operator*=(const Matrix& c) { *this = *this * c; return *this; } Matrix operator^(int k) const { //返回*this^k Matrix res = Eye(); Matrix step(*this); while (k) { if (k & 1) res *= step; k >>= 1; step *= step; } return res; } Matrix Eye() const { Matrix a; for (int i = 0; i < N; i++) a.val[i][i] = 1; return a; } void out() const { for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) cout << val[i][j] << " "; cout << "\n"; } } T* operator[](int i) { return val[i]; }};typedef long long LL;const int MOD = 10000007;int main() { int n, k, a, b, t; while (cin >> n >> k) { read(a); read(b); int s = a + b; for (int i = 2; i < n; i++) { //{找出初始S中最大的两个数a,b read(t); if (t > a) { if (t > b) { if (a < b) a =t; else b = t; } else a = t; } else if (t > b) b = t; //} s = (s + t) % MOD; } if (b > a) swap(a, b); // 假设a>=b LL aa[3][3]={{1,1,1},{0,1,1},{0,1,0}}; Matrix<LL,3,MOD> A(aa), X, Y; X[0][0] = s, X[1][0] = a, X[2][0] = b; Y = (A^k) * X; cout << Y[0][0] << "\n"; } return 0;}
1 0
- hdu5171 GTY's birthday gift(BestCoder Round #29 1002)
- BestCoder Round#29 1002 GTY's birthday gift
- hdu5171---GTY's birthday gift
- hdu5171 GTY's birthday gift
- hdu 5171 GTY's birthday gift (BestCoder Round #29)
- HDU5171 GTY's birthday gift(矩阵快速幂)
- HDU5171 GTY's birthday gift —— 矩阵快速幂
- 【BestCoder】 HDOJ 5171 GTY's birthday gift
- BestCoder Round #29——A--GTY's math problem(快速幂(对数法))、B--GTY's birthday gift(矩阵快速幂)
- hdu5171 GTY's birthday gift 矩阵快速幂求斐波那契前n项和,矩阵快速幂模板
- bc 29 GTY's birthday gift(矩阵快速幂)
- HDU 5171GTY's birthday gift
- Hdu 5172 GTY's birthday gift
- HDU 5171 GTY's birthday gift
- HDOJ-5171-GTY's birthday gift
- HDU 5171 GTY's birthday gift
- 【Best Coder】#29 B GTY's birthday gift(快速幂|mod的时候记得负!)
- 【CUGBACM15级BC第29场 B】hdu 5171 GTY's birthday gift
- 关于滚回csdn
- Splay(hdu4441Queue Sequence)好题
- 【java编程】反射之更改成员变量
- UILabel字体加粗等属性和特效
- 一个简单的groovy script生成的class文件及其反编译
- hdu5171 GTY's birthday gift(BestCoder Round #29 1002)
- Net总结
- 优化AJAX提交到Handler的ProcessRequest方法
- 每天一点数据库之-----Day 3 数据的增改删
- 记录一些有用的网站
- 写在前面的话
- 嵌入式设计及Linux驱动开发指南——基于ARM9处理器
- 时空上下文视觉跟踪(STC)算法的解读与代码复现
- 文件过滤驱动实现目录重定向(一)