题意

有一个大小为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. 在activity之间通过静态变量传递数据

    在activity之间通过静态变量传递数据 一.简介 主要作用:解决intent不能传递非序列化的对象 评价:简单方便,但是容易发生内存泄露,所以要及时回收内存 二.具体操作 1.在传输数据的页面弄好 ...

  2. Android程序的安装和打包

    Android程序的安装和打包

  3. jQuery 中$.ajax()方法参数详解

    $.ajax({ url:'test.do', data:{id:,name:'xiaoming'}, type:'post', dataType:'json', success:function(d ...

  4. Bootstrap 与 IE 兼容模式 关系讲解

    IE 兼容模式 Bootstrap 不支持 IE 古老的兼容模式.为了让 IE 浏览器运行最新的渲染模式下,建议将此 <meta> 标签加入到你的页面中:Copy <meta htt ...

  5. Wannafly挑战赛14E无效位置

    https://www.nowcoder.com/acm/contest/81/E 给一个1-base数组{a},有N次操作,每次操作会使一个位置无效.一个区间的权值定义为这个区间里选出一些数的异或和 ...

  6. 你真的掌握 LVS、Nginx 及 HAProxy 的工作原理吗

    你真的掌握 LVS.Nginx 及 HAProxy 的工作原理吗 当前大多数的互联网系统都使用了服务器集群技术,集群是将相同服务部署在多台服务器上构成一个集群整体对外提供服务,这些集群可以是 Web ...

  7. MySQLdb和PIL安装

    最近将个人博客部署到树莓派上海真是颇费周折,尤其是在MySQLdb和PIL的安装上 MySQLdb 先说Windows吧(比较简单) 直接pip安装即可或者下载编译版更方便:http://source ...

  8. Highcharts 动态图

    Highcharts 动态图 每秒更新曲线图 chart.events chart.event 属性中添加 load 方法(图表加载事件).在 1000 毫秒内随机产生数据点并生成图表. chart: ...

  9. 通过windows的超级终端连接华为交换机

    如果你的电脑没有带COM接口 可以找一个COM--->USB的转换器 我前面有介绍过这么安装COM转USB设备的驱动 2 先打开你电脑的设备管理器 看看你的com接口数字编号 这里看到的是COM ...

  10. Docker - 在Ubuntu 14.04 Server上的安装Docker

    在 Ubuntu 14.04 Server 上安装过程是最简单的, 其满足了安装 Docker的所有要求,只需要执行如下安装脚本即可. 如果你有可能,请使用14.04版本的Ubuntu, 避免给自己挖 ...