hdu5171 GTY's birthday gift
2015-07-20 11:11
106 查看
题意:给定一个数列含有n个数,执行k次操作(n,k<109),每次操作从中取出2个数,求和加起来在放回原数列(下一次操作对新数列进行操作) 求 最后数列可能的最大总和
分析:首先首次次操作应该选取当前数列中最大的2个数a和b (a>b) 而第二次应该选取a+b
和a 第三次 为a+b+a和a+b 这样每次新构成的数,是上一次选取的2个数之和,a和b的系数 相当于斐波那契数列。
对于快速求斐波那契数列可以构造矩阵
1 1
1 0
而这题加上对斐波那契数列的求和,所以可以构造
1 1 0
1 0 0
1 1 1
这样的矩阵 来附加求和功能
分析:首先首次次操作应该选取当前数列中最大的2个数a和b (a>b) 而第二次应该选取a+b
和a 第三次 为a+b+a和a+b 这样每次新构成的数,是上一次选取的2个数之和,a和b的系数 相当于斐波那契数列。
对于快速求斐波那契数列可以构造矩阵
1 1
1 0
而这题加上对斐波那契数列的求和,所以可以构造
1 1 0
1 0 0
1 1 1
这样的矩阵 来附加求和功能
#include <iostream> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <map> #include<stack> #define inf 0x3f3f3f3f #define ll long long #define bug puts("bugbugbug"); using namespace std; const int maxn = 20; const int maxm = 20; ll mod=10000007; int a[100005]; struct Matrix { int n, m; ll a[maxn][maxm]; void clear() { n = m = 0; memset(a, 0, sizeof(a)); } Matrix operator * (const Matrix &b) const { //实现矩阵乘法 Matrix tmp; tmp.n = n; tmp.m = b.m; for (int i = 0; i < n; i++) for (int j = 0; j < b.m; j++) tmp.a[i][j] = 0; for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) { if (!a[i][j]) continue; for (int k = 0; k < b.m; k++) tmp.a[i][k] += a[i][j] * b.a[j][k], tmp.a[i][k] %= mod; } return tmp; } void Copy(const Matrix &b) { n = b.n, m = b.m; for (int i = 0; i < n; i++) for(int j = 0; j < m; j++) a[i][j] = b.a[i][j]; } void unit(int sz) { n = m = sz; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) a[i][j] = 0; a[i][i] = 1; } } }; Matrix A, B,C; Matrix Matrix_pow(Matrix A, ll k, ll mod) { //矩阵快速幂 Matrix res; res.clear(); res.n = res.m = A.n; for (int i = 0; i < A.n; i++) res.a[i][i] = 1; while(k) { if (k & 1) res.Copy(A * res); k >>= 1; A.Copy(A * A); } return res; } int main() { int n,k; A.clear(); A.n=A.m=3; A.a[0][0]=1;A.a[0][1]=1;A.a[0][2]=0; A.a[1][0]=1;A.a[1][1]=0;A.a[1][2]=0; A.a[2][0]=1;A.a[2][1]=1;A.a[2][2]=1; while(~scanf("%d%d",&n,&k)) { int ans=0; for(int i=0;i<n;i++){ scanf("%d",&a[i]); ans=(ans+a[i])%mod; } B.clear(); B.Copy(Matrix_pow(A,k,mod)); C.n=3;C.m=1; sort(a,a+n); C.a[0][0]=a[n-1]; C.a[1][0]=a[n-2]; C.a[2][0]=0; C.Copy(B*C); printf("%d\n",(ans+C.a[2][0])%mod); } }
相关文章推荐
- 禅与 Objective-C 编程艺术 (Zen and the Art of the Objective-C Craftsmanship 中文翻译)
- Linearlayout添加监听事件
- 深度学习之Matlab 转C++在iOS上测试CNN手型识别
- 【POJ3268】Silver Cow Party 最短
- 【Z13区】记忆留住深刻过往,博客写出平淡事迹【博客首篇】
- 小练习
- Algorithms—149.Max Points on a Line
- LeetCode - Sliding Window Maximum
- java关于开始新项目的问题
- Android 自定义View (二) 进阶
- 幻读和不可重复读的区别
- 压缩感知在稀疏信道估计中的应用
- 失控--阅读笔记共同进化
- [机器迁移]如何通过网络快速传输海量(小)文件
- 对android应用程序目录结构的说明
- ITOO高校云平台之考评系统项目总结
- xlsxwriter使用
- c 简单程序
- Morris二叉树遍历算法
- ASP.NET MVC 中出现的 方法 中的 this 关键字 用法 (this HtmlHelper helper)