Sol

首先,考虑这个要怎么搞...让总和最大的方法就是选出当前集合中最大的两个数相加放入集合中就可以了,证明非常简单,当前集合的和为x,它的和只会一直往后增加,所以只需要找到最大的两个数的和加入便是最佳答案.知道了这个以后,手动递推一下就是一个斐波拉契数列.

然后斐波拉契数列数列自然可以矩乘,但是矩阵乘法不能解决负数斐波拉契问题.而且,一正一负就不是斐波拉契数列的递推了.递推应该是这个样子.

\(F_2=F_1+F_0,F_3=F_2+F_1=F_1+F_1+F_0...F_n=F_1*(n-1)+F_0\)

所以我们就可以直接 \(O(1)\) 得到需要进行多少次操作使得出现两个正数,原来的 \(F_1\) 就已经是一个正数了,所以操作数为 \(\left \lfloor -F_0/F_1 \right \rfloor +1\) 求和用等差数列求和公式,剩下的直接矩乘.

剩下的问题就是斐波拉契数列求和的问题了,我们知道斐波拉契数列前n项和 \(\sum_{i=0}^{n}F_i=F_{n+2}-1\) 虽然这个前两项并不是1,但是可以得到相似的结论 \(\sum_{i=0}^{n}F_i=F_{n+2}-F_1\) .

在这里我给出证明,证明也很简单,数学归纳法.

证明: \(n=0\) 时显然成立, \(F_0=F_2-F_1\) 移项一下就是递推式

当 \(n>0\) 时,假设有 \(\sum_{i=0}^{n}F_i=F_{n+2}-F_1\)

只需要证明在 \(n+1\) 时同样成立即可.

\(\sum_{i=0}^{n+1}F_i=\sum_{i=0}^{n}F_i +F_{n+1}=F_{n+2}-F_1+F_{n+1}=F_{n+3}-F_1\)

即在 \(n+1\) 处依然成立,证毕.

PS:当然这个也可以构造一个矩阵同时记录前缀和即可.

PS:我代码码风改了改...应该可以还算可阅吧...QAQ

Code

/**************************************************************
Problem: 4547
User: BeiYu
Language: C++
Result: Accepted
Time:324 ms
Memory:2076 kb
****************************************************************/ #include<cstdio>
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std; #define debug(a) cout<<#a<<"="<<a<<endl
typedef long long LL;
typedef vector<LL> Vec;
typedef vector<Vec> Mat;
const LL Mo = 10000007;
const int N = 100005; Mat operator * (const Mat &A,const Mat &B){
Mat C(2,Vec(2));
for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++)
C[i][j]=(C[i][j]+A[i][k]*B[k][j])%Mo;
return C;
}
Mat operator ^ (Mat A,LL b){
Mat res(2,Vec(2));
res[0][0]=1,res[0][1]=0,res[1][0]=0,res[1][1]=1;
for(;b;b>>=1,A=A*A){
if(b&1) res=res*A;
}return res;
} LL n,k;LL a[N];
inline LL in(LL x=0,char ch=getchar(),int v=1){
while(ch>'9'||ch<'0') v=ch=='-'?-1:1,ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*v;
}
int main(){
n=in(),k=in();
for(int i=1;i<=n;i++) a[i]=in();
sort(a+1,a+n+1);
LL tmp,f0=a[n-1],f1=a[n],ans=0;
for(int i=1;i<n-1;i++) ans=(ans+a[i]+Mo)%Mo;
if(f0<0){
tmp=-f0/f1+1;
if(tmp<=k){
k-=tmp,ans=(ans+(f0+f0+f1*(tmp-1))*(tmp)/2%Mo)%Mo;
f0=(f0+f1*tmp%Mo)%Mo;
if(f0>f1) swap(f0,f1);
}
}
Mat F(2,Vec(2));F[0][0]=0,F[0][1]=1,F[1][0]=1,F[1][1]=1;
Mat Fn=F^(k+2);
ans=(ans+f0*Fn[0][1]%Mo+f1*Fn[1][1]%Mo)%Mo;
ans=(ans-f1+Mo)%Mo;
printf("%lld\n",ans);
return 0;
}

  

BZOJ 4547: Hdu5171 小奇的集合的更多相关文章

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

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

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

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

  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】小奇的集合 矩阵乘法 + 递推

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

  6. bzoj 4547 小奇的集合

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

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

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

  8. bzoj4547 小奇的集合

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

  9. [HDU517] 小奇的集合

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

随机推荐

  1. 15款优秀移动APP产品原型设计工具

    一新来小盆友问:“移动产品原型设计都用啥工具?” 答:“@#¥……&%*” 又问:“能详细说下各个工具吗?我比较一下” “……” 好吧,谁让我那么的爱分享而你又是小美女呢 ———————正文开 ...

  2. (自用)专业排版套装:CTeX + TeXStudio

    \documentclass[UTF8,landscape]{ctexart}%UTF8,ctexart中文支持,landscape横向版面 \usepackage{tikz}%画图 \usepack ...

  3. 【OpenCV】边缘检测:Sobel、拉普拉斯算子

    推荐博文,博客.写得很好,给个赞. Reference Link : http://blog.csdn.net/xiaowei_cqu/article/details/7829481 一阶导数法:梯度 ...

  4. new和alloc init的区别

    背景说明,new是较为老式的写法,后来发现只有一个new不好使,才引入了alloc和init这种写 法,保留new一是向后兼容,二是很多时候是一种更简单的写法.其实是一样的,new在内部调用 的all ...

  5. Intent启动一个新的页面

    一,Intent(目的) 的分类 显式 Intent 构造函数重载之一: Intent intent = new Intent(FirstActivity.this,SecondActivity.cl ...

  6. 如何使Python完美升级到新版本

    这里提供一种解决的方法 (加上一句话,发现一个新问题:这种方法yum update 后,需要将/usr/bin下的python文件删除,然后执行: # ln -s /usr/local/python2 ...

  7. 在 docker中 运行 mono /jexus server 并部署asp.net mvc站点

    http://linuxdot.net/bbsfile-3988 1.  安装 docker:      // docker 1.7 新版 安装非常容易,理论上说,在主流的任意linux发行版上都可以 ...

  8. Redis-cluster集群【第三篇】:redis主从

    Redis主从复制原理: 通过把这个RDB文件或AOF文件传给slave服务器,slave服务器重新加载RDB文件,来实现复制的功能! 复制的话:主服务器可以有多个从服务器!!!  不仅这样从服务器还 ...

  9. 安装 SQL server 2008 R2

    操作系统:WIN7 问题: The Windows Installer Service could not be accessed. This can occur if the Windows Ins ...

  10. git alias和gitconfig配置

    [alias] st = status -sb co = checkout br = branch mg = merge ci = commit ds = diff --staged dt = dif ...