题意

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

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

GXZlegend的题解

显然每次选择集合中最大的两个数相加即可。

如果最大的两个数都是正数,那么结果显然也是正数并且比它们都要大,即\((b,a)→(a,a+b)\),所以可以使用矩阵乘法来解决。

具体过程:

\[\left[
\begin{matrix}
a & b &s
\end{matrix}
\right]
*
\left[
\begin{matrix}
1 & 1& 1\\
1 & 0& 0\\
0 & 0& 1
\end{matrix}
\right]=
\left[
\begin{matrix}
a+b & a &s+a
\end{matrix}
\right]
\]

如果最大的两个数都是负数,那么结果显然也是负数并且比它们都要小,因此直接选择它们相加k次即可。

如果这两个数一正一负,那么每次负数会变大,由于数的范围只有\(10^5\),因此可以暴力操作直到加到正数或者没有操作机会,然后矩乘即可。

时间复杂度\(O(a+\log k)\)

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;
rg char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') w=-1;
ch=getchar();
}
while(isdigit(ch))
data=data*10+ch-'0',ch=getchar();
return data*w;
}
template<class T>il T read(rg T&x){
return x=read<T>();
}
typedef long long ll; co int mod=1e7+7;
struct data{
ll v[3][3];
data(int x=0){memset(v,0,sizeof v);v[0][0]=v[1][1]=v[2][2]=x;}
ll*operator[](int a){return v[a];};
co ll*operator[](int a)co{return v[a];};
data operator*(co data&a)co{
data re;
for(int k=0;k<3;++k)
for(int i=0;i<3;++i) if(v[i][k])
for(int j=0;j<3;++j)
re[i][j]=(re[i][j]+v[i][k]*a[k][j])%mod;
return re;
}
}A;
int a[100001];
data pow(data x,int y){
data re(1);
while(y){
if(y&1) re=re*x;
x=x*x,y>>=1;
}
return re;
}
int main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
int n=read<int>(),k=read<int>();
ll sum=0;
for(int i=1;i<=n;++i)
sum+=read(a[i]);
std::sort(a+1,a+n+1);
if(a[n]<=0) printf("%lld\n",((sum+(ll)(a[n]+a[n-1])*k)%mod+mod)%mod);
else{
for(sum-=a[n];k&&a[n-1]<0;--k)
a[n-1]+=a[n],sum+=a[n-1];
A[0][0]=A[0][1]=A[0][2]=A[1][0]=A[2][2]=1,A=pow(A,k+1);
printf("%lld\n",((sum+a[n]*A[0][2]+a[n-1]*A[1][2])%mod+mod)%mod);
}
return 0;
}

BZOJ4547 Hdu5171 小奇的集合的更多相关文章

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

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

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

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

  3. 【BZOJ4547】Hdu5171 小奇的集合 矩阵乘法

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

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

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

  5. BZOJ 4547: Hdu5171 小奇的集合

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

  6. bzoj 4547 小奇的集合

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

  7. bzoj4547 小奇的集合

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

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

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

  9. [HDU517] 小奇的集合

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

随机推荐

  1. Python笔试、面试 【必看】

    本文由EarlGrey@编程派独家编译,转载请务必注明作者及出处. 原文:Sheena@codementor 译文:编程派 引言 想找一份Python开发工作吗?那你很可能得证明自己知道如何使用Pyt ...

  2. #if 0 #endif && #if 1 #endif ----待整理

    在看一个 usbcan 的上位机例程中发现了这个,于是百度下,记录下来.(参考:http://nevel.cnblogs.com/p/6378035.html)

  3. html合并单元格

    在合并的首位置加上colspan或者rowspan属性即可 code: <html>   <body>   <h4>横跨两列的单元格:</h4> < ...

  4. flask学习(十二):for循环遍历

    一. 字典的遍历 语法和python一样,可以使用items().keys().values().iteritems().iterkeys().itervalues() {% for k, v in ...

  5. 015PHP基础知识——流程控制(三)

    <?php /** *流程控制(三) */ /* 循环结构: while(){ } */ //设置脚本最长执行时间:100秒 //set_time_limit(100); $lantian = ...

  6. 004——数组(四)array_search() array_change_key_case() array_chunk() array_combine() array_diff() array_diff_key() array_diff_assoc

    <?php /** * in_array() 判断一个内容是否在数组中: */ /*$arr=array(1,2,3,4,5); if (in_array('1',$arr,TRUE)){ // ...

  7. C#学习历程(三)[基础概念]

    >>简单描述OOP 面向对象编程是由面向过程编程发展而来,不再注重于具体的步骤,而是更多的聚焦于对象. 以对象为载体,然后去完善对象的特点(属性),然后实现对象的具体的功能,同时处理对象与 ...

  8. sql 日志统计-日、周、月活跃数

    近日网站需求:统计日志表的 日.周.月活跃数.最终研究了出来了,分享给大家看下.  如果有更好的sql语句也可以评论下方. --日活跃量 ), cr.AddTime, )as addtimt,COUN ...

  9. 让nodejs在iis上运行

    node在IIS上运行的好处: Tomasz的回答是我见过最棒的: 使用iisnode模块在IIS中托管node.js应用程序来取代自托管node.exe进程的优势在于: · 进程管理. Iisnod ...

  10. 一个功能丰富的 jQuery 树形插件 z-tree

    链接 如果你的树 很复杂, 需要拖拽功能, 还可以考虑用这个 另外还有一个目前在用 Dynatree 如果一般的树, 还是自己写一个, 也很轻松,    如果有一两个复杂的点, 可以参考ZTree