【bzoj4547】【小奇的集合】【矩阵乘法】
2016-05-17 10:20
323 查看
有一个大小为n的可重集S,小奇每次操作可以加入一个数a+b(a,b均属于S),求k次操作后它可获得的S的和的最大
值。(数据保证这个值为非负数)
对于100%的数据,有 n<=10^5,k<=10^9,|ai|<=10^5
3 6
题解:
首先如果最大值和次大值都是正数肯定是这两个数向上累加.
如果最大值和次大值一正一负,那就先把负数加成正数.
之后的累加操作显然可以用矩阵乘法加速.
代码:
值。(数据保证这个值为非负数)
Input
第一行有两个整数n,k表示初始元素数量和操作数,第二行包含n个整数表示初始时可重集的元素。对于100%的数据,有 n<=10^5,k<=10^9,|ai|<=10^5
Output
输出一个整数,表示和的最大值。答案对10000007取模。Sample Input
2 23 6
Sample Output
33题解:
首先如果最大值和次大值都是正数肯定是这两个数向上累加.
如果最大值和次大值一正一负,那就先把负数加成正数.
之后的累加操作显然可以用矩阵乘法加速.
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define P 10000007 #define N 100010 #define ll long long using namespace std; int v ,n,k; long long s; struct use{ ll a[5][5]; use(){memset(a,0,sizeof(a));} friend use operator*(use a,use b){ use c; for (int i=1;i<=3;i++) for (int j=1;j<=3;j++) for (int k=1;k<=3;k++) (c.a[i][j]+=(a.a[i][k]*b.a[k][j])%P)%=P; return c; } friend use operator^(use a,int b){ use ans; for (int i=1;i<=3;i++) ans.a[i][i]=1; for (int i=b;i;i>>=1,a=a*a) if (i&1) ans=ans*a; return ans; } }a,ans; int main(){ scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) scanf("%d",&v[i]),(s+=(ll)v[i])%=P; sort(v+1,v+n+1); while (v[n-1]<0&&k){ v[n-1]=(v +v[n-1])%P; (s+=(ll)v[n-1])%=P;k--; } a.a[1][1]=1;a.a[1][2]=1;a.a[1][3]=0; a.a[2][1]=1;a.a[2][2]=0;a.a[2][3]=0; a.a[3][1]=1;a.a[3][2]=1;a.a[3][3]=1; ans.a[1][1]=v ;ans.a[2][1]=v[n-1];ans.a[3][1]=s; ans=(a^k)*ans;int x=(ans.a[3][1]+P)%P; printf("%d",x); }
相关文章推荐
- CI框架整合widget(页面格局)的方法
- Codeforces Round #353 (Div. 2)-A. Infinite Sequence(模拟)
- Android 中如何实现 显示和隐藏软键盘——附Demo下载
- Linux errno 错误对照表
- Xcode 下载地址
- [Android] 带有输入框(EditText)的提示框(AlertDialog)
- UVa 297 Quadtrees 递归
- Socket编程
- tess-two编译失败-----NDK build for target x86_64 results in error
- Xcode 之bug篇
- 迅雷之CDN加速下载/离线下载
- Cassandra在Windows上安装及使用方法
- 智能化变电站辅助系统与生产系统结合的未来发展方向
- php 删除目录及目录下文件
- android 蓝牙
- intellij快捷键
- C#中泛型方法与泛型接口
- 东南大学2016年考博信息汇总
- HTTP Live Streaming直播(iOS直播)技术分析与实现
- rpm包下载网站