【BZOJ4547】Hdu5171 小奇的集合

Description

有一个大小为n的可重集S,小奇每次操作可以加入一个数a+b(a,b均属于S),求k次操作后它可获得的S的和的最大值。(数据保证这个值为非负数)

Input

第一行有两个整数n,k表示初始元素数量和操作数,第二行包含n个整数表示初始时可重集的元素。

对于100%的数据,有 n<=10^5,k<=10^9,|ai|<=10^5

Output

输出一个整数,表示和的最大值。答案对10000007取模。

Sample Input

2 2
3 6

Sample Output

33

题解:首先贪心的想,我们肯定是选取最大值和次大值,然后进行如下讨论:

如果最大值和次大值都>=0,则我们每次用最大值+次大值得到新的最大值,由于K是10^9,所以用矩乘加速即可。

如果只有次大值<0,那么我们先不断用最大值+次大值得到新的次大值,直到次大值>=0,然后同上。

如果最大值<0,那么不断将最大值和次大值相加即可。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll P=10000007;
int n;
ll m,a1,a2,sum;
struct M
{
ll a[5][5];
M () {memset(a,0,sizeof(a));}
ll * operator [] (int b) {return a[b];}
M operator * (M b)
{
M c;
int i,j,k;
for(i=1;i<=3;i++) for(j=1;j<=3;j++) for(k=1;k<=3;k++) c[i][j]=(c[i][j]+a[i][k]*b[k][j])%P;
return c;
}
}ans,tr;
void pm(ll y)
{
while(y)
{
if(y&1) ans=ans*tr;
tr=tr*tr,y>>=1;
}
}
int main()
{
scanf("%d%lld",&n,&m);
int i;
ll a;
a1=a2=-1<<30;
for(i=1;i<=n;i++)
{
scanf("%lld",&a),sum=(sum+a+P)%P;
if(a>a1) a2=a1,a1=a;
else a2=max(a2,a);
}
if(a1<0)
{
printf("%lld",(sum+(a1+a2+P+P)*m)%P);
return 0;
}
while(a2<0&&m) a2=a1+a2,sum=(sum+a2)%P,m--;
if(!m)
{
printf("%lld",sum);
return 0;
}
tr[1][1]=tr[1][2]=tr[1][3]=tr[2][1]=tr[2][3]=tr[3][3]=1;
ans[1][1]=a1,ans[1][2]=a2,ans[1][3]=sum;
pm(m);
printf("%lld",ans[1][3]);
return 0;
}

【BZOJ4547】Hdu5171 小奇的集合 矩阵乘法的更多相关文章

  1. bzoj4547: Hdu5171 小奇的集合(矩阵乘法)

    4547: Hdu5171 小奇的集合 题目:传送门 题解: 做一波大佬们的坑...ORZ 不得不说,我觉得矩阵很简单啊,就一个3*3的(直接看代码吧) 给个递推柿纸:f[i]=f[i-1]+max1 ...

  2. 【BZOJ-4547】小奇的集合 矩阵乘法 + 递推

    4547: Hdu5171 小奇的集合 Time Limit: 2 Sec  Memory Limit: 256 MBSubmit: 175  Solved: 85[Submit][Status][D ...

  3. BZOJ4547 Hdu5171 小奇的集合 【矩阵快速幂优化递推】

    BZOJ4547 Hdu5171 小奇的集合 Description 有一个大小为n的可重集S,小奇每次操作可以加入一个数a+b(a,b均属于S),求k次操作后它可获得的S的和的最大值.(数据保证这个 ...

  4. BZOJ4547 Hdu5171 小奇的集合

    题意 有一个大小为n的可重集S,小奇每次操作可以加入一个数a+b(a,b均属于S),求k次操作后它可获得的S的和的最大值.(数据保证这个值为非负数) 对于100%的数据,有 n<=10^5,k& ...

  5. BZOJ 4547: Hdu5171 小奇的集合

    Sol 首先,考虑这个要怎么搞...让总和最大的方法就是选出当前集合中最大的两个数相加放入集合中就可以了,证明非常简单,当前集合的和为x,它的和只会一直往后增加,所以只需要找到最大的两个数的和加入便是 ...

  6. bzoj4547 小奇的集合

    当序列中最大和次大都是负数的时候,其相加会是一个更小的负数,因此答案为(Σai)+(m1+m2)*k,如果最大是正数次大是负数,那么一直相加直到两个数都为正数,当最大和次大都是正数时,做一下矩阵乘法即 ...

  7. bzoj 4547 小奇的集合

    Description 有一个大小为n的可重集S,小奇每次操作可以加入一个数a+b(a,b均属于S),求k次操作后它可获得的S的和的最大 值.(数据保证这个值为非负数) Input 第一行有两个整数n ...

  8. [HDU517] 小奇的集合

    题目链接 显然有贪心每次选择最大的两个数来做. 于是暴力地把最大的两个数调整到非负(暴力次数不超过1e5),接下来使用矩阵乘法即可. \[ \begin{pmatrix} B'\\S'\\T' \en ...

  9. 【BZOJ 4547】【HDU 5157】小奇的集合

    http://www.lydsy.com/JudgeOnline/problem.php?id=4547 本蒟蒻并不会矩乘求Fibonacci数列前缀和,所以果断分块打表,常数竟然比矩乘要小! PS: ...

随机推荐

  1. FAT AP v200R005 配置二层透明模式(web&命令行,开局)

    背景: vlan123:用户业务vlan,192.168.1.0/24 Vlan2001:管理vlan,172.168.129.0/24 vlan1:默认vlan,不建议使用. 注意事项: 配置服务集 ...

  2. SpringMVC 异常记录

    在使用SpringMVC中开发过程中,遇到的一些坑,简单记录一下. 1.The request sent by the client was syntactically incorrect 从字面意思 ...

  3. mybatis学习知识

    目录 1,目录 2,介绍 3,快速入门 4,配置XML 5,xml文件映射 6,动态sql 7,java api 8,Statement Builders 9,日志 1,介绍 1.1 介绍 1.1.1 ...

  4. 解决 adb devices :???????????? no permissions 方法

  5. 关于new与=号创建对象的区别

    (1)先定义一个名为str的对String类的对象引用变量:String str: (2)[在[栈]中查找有没有存放值为"abc"的地址,如果没有,则开辟一个存放字面值为" ...

  6. 【搞机】Apple Pencil 开箱

    前言 上次入手了新的iPad Pro .好开心呢. 然后发现官方的笔不错呢~ 后来,苹果官方的12期免息分期又回来啦~ 买买买!!! 上图 体验 官方的笔真的不愧叫Pencil ,完美模拟铅笔的手感. ...

  7. Sublime Text 2 和 Verilog HDL

    Sublime Text 2 和 Verilog HDL Date  Fri 04 July 2014 Tags Sublime Text / Vivado Sublime Text 代码编辑器之于程 ...

  8. @property (nonatomic,retain)中的nonatom和retain的意思

    转自:http://yuanshoupeng2005.blog.163.com/blog/static/68235027201235113952886/ http://baike.baidu.com/ ...

  9. linux下时间操作1

    本文是对我之前写的文章:C++时间操作 的更深入补充.之前那个文章就是一个快速入门的东西,后面力图把一些更深入的细节补充完整. 时间分类的基本介绍 在介绍一些时间相关的操作函数之前,先来介绍一下lin ...

  10. 李洪强iOS开发OC[001]-NSLog函数的使用方法