BZOJ4547 Hdu5171 小奇的集合
题意
有一个大小为n的可重集S,小奇每次操作可以加入一个数a+b(a,b均属于S),求k次操作后它可获得的S的和的最大值。(数据保证这个值为非负数)
对于100%的数据,有 n<=105,k<=109,|ai|<=10^5
GXZlegend的题解
显然每次选择集合中最大的两个数相加即可。
如果最大的两个数都是正数,那么结果显然也是正数并且比它们都要大,即\((b,a)→(a,a+b)\),所以可以使用矩阵乘法来解决。
具体过程:
\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 小奇的集合的更多相关文章
- BZOJ4547 Hdu5171 小奇的集合 【矩阵快速幂优化递推】
BZOJ4547 Hdu5171 小奇的集合 Description 有一个大小为n的可重集S,小奇每次操作可以加入一个数a+b(a,b均属于S),求k次操作后它可获得的S的和的最大值.(数据保证这个 ...
- bzoj4547: Hdu5171 小奇的集合(矩阵乘法)
4547: Hdu5171 小奇的集合 题目:传送门 题解: 做一波大佬们的坑...ORZ 不得不说,我觉得矩阵很简单啊,就一个3*3的(直接看代码吧) 给个递推柿纸:f[i]=f[i-1]+max1 ...
- 【BZOJ4547】Hdu5171 小奇的集合 矩阵乘法
[BZOJ4547]Hdu5171 小奇的集合 Description 有一个大小为n的可重集S,小奇每次操作可以加入一个数a+b(a,b均属于S),求k次操作后它可获得的S的和的最大值.(数据保证这 ...
- 【BZOJ-4547】小奇的集合 矩阵乘法 + 递推
4547: Hdu5171 小奇的集合 Time Limit: 2 Sec Memory Limit: 256 MBSubmit: 175 Solved: 85[Submit][Status][D ...
- BZOJ 4547: Hdu5171 小奇的集合
Sol 首先,考虑这个要怎么搞...让总和最大的方法就是选出当前集合中最大的两个数相加放入集合中就可以了,证明非常简单,当前集合的和为x,它的和只会一直往后增加,所以只需要找到最大的两个数的和加入便是 ...
- bzoj 4547 小奇的集合
Description 有一个大小为n的可重集S,小奇每次操作可以加入一个数a+b(a,b均属于S),求k次操作后它可获得的S的和的最大 值.(数据保证这个值为非负数) Input 第一行有两个整数n ...
- bzoj4547 小奇的集合
当序列中最大和次大都是负数的时候,其相加会是一个更小的负数,因此答案为(Σai)+(m1+m2)*k,如果最大是正数次大是负数,那么一直相加直到两个数都为正数,当最大和次大都是正数时,做一下矩阵乘法即 ...
- 【BZOJ 4547】【HDU 5157】小奇的集合
http://www.lydsy.com/JudgeOnline/problem.php?id=4547 本蒟蒻并不会矩乘求Fibonacci数列前缀和,所以果断分块打表,常数竟然比矩乘要小! PS: ...
- [HDU517] 小奇的集合
题目链接 显然有贪心每次选择最大的两个数来做. 于是暴力地把最大的两个数调整到非负(暴力次数不超过1e5),接下来使用矩阵乘法即可. \[ \begin{pmatrix} B'\\S'\\T' \en ...
随机推荐
- C++ 知识点积累---待整理
- python基础方法
一.忽略大小写相等upper(),lower() def cmp(str1,str2): return str1.upper()==str2.upper() list1 = 'MAC' list2 = ...
- C#转译字符
C#转义字符: 一种特殊的字符常量 以反斜线"\"开头,后跟一个或几个字符 具有特定的含义,不同于字符原有的意义,故称“转义”字符. 主要用来表示那些用一般字符不便于表示的控制代码 ...
- iPhone 和Android应用,特殊的链接:打电话,短信,email
下面的这篇文章主要是说,网页中的链接如何写,可以激活电话的功能. 例如,页面中展示的是一个电话号码,当用户在手机浏览器里面点击这个电话号码的时候,手机会弹出拨号的面板,或者是短信程序会启动等. 1. ...
- JDK的多线程与并发库
1.创建多线程 public class MultiThread { public static void main(String[] args) { // 通过继承Thread类 Thread th ...
- [感悟]马士兵Java自学之路——(精华版)
JAVA自学之路 一: 学会选择 为了就业,不少同学参加各种各样的培训. 决心做软件的,大多数人选的是java,或是.net,也有一些选择了手机.嵌入式.游戏.3G.测试等. 那么究竟应该选择什么方向 ...
- php中mysql_fetch_row() 和mysql_fetch_array之间有什么区别
mysql_fetch_row是从结果集取出1行数组,作为枚举 mysql_fetch_array是从结果集取出一行数组作为关联数组,或数字数组,两者兼得eg:$sql="select ab ...
- Java线程的五种状态详解
状态转换图 1.new状态:通过new关键字创建了Thread或其子类的对象 2.Runnable状态:即就绪状态.可从三种状态到达,new状态的Thread对象调用start()方法,Running ...
- QT帮助文档 英文
http://doc.qt.io/archives/qtquick-components-symbian-1.1/qml-button.html
- 本地如何搭建IPv6环境测试你的APP(转)
IPv6的简介 IPv4 和 IPv6的区别就是 IP 地址前者是 .(dot)分割,后者是以 :(冒号)分割的(更多详细信息自行搜索). PS:在使用 IPv6 的热点时候,记得手机开 飞行模式 哦 ...