题目链接

显然有贪心每次选择最大的两个数来做。

于是暴力地把最大的两个数调整到非负(暴力次数不超过1e5),接下来使用矩阵乘法即可。

\[\begin{pmatrix}
B'\\S'\\T'
\end{pmatrix}
=
\begin{pmatrix}
1&1&0\\
1&0&0\\
1&1&1
\end{pmatrix}
\begin{pmatrix}
B\\S\\T
\end{pmatrix}
\]

#include <bits/stdc++.h>
using namespace std;
const int mod=1e7+7; struct Node {
int a[3][3];
int *operator[](const int&d) {return a[d];}
const int *operator[](const int&d) const{return a[d];}
Node operator*(const Node&b) const{
Node c;
memset(&c,0,sizeof c);
for(int i=0; i<3; ++i)
for(int k=0; k<3; ++k) if(a[i][k])
for(int j=0; j<3; ++j)
c[i][j]=(c[i][j]+1LL*a[i][k]*b[k][j]%mod)%mod;
return c;
}
Node pow(int y) {
Node c,x=*this;
for(int i=0; i<3; ++i)
for(int j=0; j<3; ++j) c[i][j]=(i==j);
for(; y; y>>=1,x=x*x) if(y&1) c=c*x;
return c;
}
} G,M; int n,k,sum,a[200010]; int main() {
scanf("%d%d",&n,&k);
for(int i=1; i<=n; ++i) {
scanf("%d",a+i);
sum=(sum+a[i]+mod)%mod;
}
sort(a+1,a+n+1);
while(a[n-1]<0&&k>0) {
a[n+1]=(a[n]+a[n-1]); n++; k--;
sum=(sum+a[n]+mod)%mod;
swap(a[n],a[n-1]);
}
if(k==0) {
printf("%d\n",sum);
return 0;
}
M[0][0]=a[n];
M[1][0]=a[n-1];
M[2][0]=sum;
G[0][0]=G[0][1]=1;
G[1][0]=1;
G[2][0]=G[2][1]=G[2][2]=1;
Node ans=G.pow(k)*M;
printf("%d\n",ans[2][0]);
return 0;
}

[HDU517] 小奇的集合的更多相关文章

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

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

  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 小奇的集合(矩阵乘法)

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

  5. BZOJ4547 Hdu5171 小奇的集合

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

  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. BZOJ 4547: Hdu5171 小奇的集合

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

  9. bzoj4547 小奇的集合

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

随机推荐

  1. pyTerra

    https://pypi.org/project/pyTerra/ pyTerra is a Python module that allows you to make requests to Mic ...

  2. 安装java1.8.0

    安装java 1.删除自带jdk rpm -e --nodeps `rpm -qa | grep java` 2.查看yum库中有哪些jdk版本. yum search java | grep jdk ...

  3. 了解dubbo+zookeeper

    一.Dubbo是什么? Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,分布式服务框架(SOA),致力于提供高性能和透明化的RPC远程 ...

  4. python3笔记十六:python匿名函数和高阶函数

    一:学习内容 lambda函数 map函数与reduce函数 filter函数 sorted函数 二:匿名函数-lambda 1.概念:不使用def这样的语句去定义函数,使用lambda来创建匿名函数 ...

  5. IDEA怎么开启终端Terminal

    方法一:在IDEA中点击view→tool window→Terminal即可开启 方法二:按住ALT+F12(如果是笔记本按不出来的话再加个Fn键)

  6. c++ / % 四舍五入 向上取整ceil 向下取整floor

     / % 四舍五入 向上取整ceil 向下取整floor #include <math.h> double floor(double x); float floorf(float x); ...

  7. ccf 201512-3 画图(90)

    ccf 201512-3 画图(90) #include<iostream> #include<cstring> #include<algorithm> using ...

  8. 手机APP缓存的获取和清理功能的实现

    package com.loaderman.appcachedemo; import android.content.pm.IPackageDataObserver; import android.c ...

  9. ip地址后面的斜杠24

    ip地址后面的斜杠24表示掩码位是24位的,即用32位二进制表示的子网掩码中有连续的24个“1”:11111111 11111111 11111111 00000000,将其转化为十进制,就是:255 ...

  10. [Python]在python中调用shell脚本,并传入参数-02python操作shell实例

    首先创建2个shell脚本文件,测试用. test_shell_no_para.sh 运行时,不需要传递参数 test_shell_2_para.sh 运行时,需要传递2个参数  test_shell ...