题目大意:在一个长度为$n$的环型序列中取出$m$个数使这$m$个数的和最大,且要求这$m$个数互不相邻。

----------------------

考虑维护$nxt$和$lst$,即一个数的前驱和后继。如果此数被选中,那么$a[now]=a[lst]+a[nxt]-a[now]$并且更新前驱和后继,再将更新过后的数扔入堆中。

反悔机制。

操作$m$次后输出$ans$即可。

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+;
int n,m,a[maxn],nxt[maxn],lst[maxn],ans,mov[maxn];
struct node{int k;};
bool operator < (node x,node y) {return a[x.k]<a[y.k];};
priority_queue<node> q;
int main()
{
scanf("%d%d",&n,&m);
if (n<m*)
{
printf("Error!");
return ;
}
for (int i=;i<=n;i++) scanf("%d",&a[i]),q.push((node){i});
for (int i=;i<n;i++) nxt[i]=i+;nxt[n]=;
for (int i=;i<=n;i++) lst[i]=i-;lst[]=n;
while(m--)
{
node now=q.top();q.pop();
while(mov[now.k])
{
now=q.top();
q.pop();
}
ans+=a[now.k];
a[now.k]=a[lst[now.k]]+a[nxt[now.k]]-a[now.k];
mov[lst[now.k]]=;
mov[nxt[now.k]]=;
lst[now.k]=lst[lst[now.k]],nxt[lst[now.k]]=now.k;
nxt[now.k]=nxt[nxt[now.k]],lst[nxt[now.k]]=now.k;
q.push((node){now.k});
}
printf("%d",ans);
return ;
}

最新文章

  1. 知乎大牛的关于JS解答
  2. python 二进制读写文件
  3. C# SortedList类概念和示例
  4. java网络---再论URL &amp; URI
  5. github与eclipse创建仓库及克隆仓库
  6. JavaScriptSerializer中日期序列化问题解决方案
  7. 字符编码GB2312、GBK、UTF-8的区别
  8. Python之 for循环\while循环
  9. Xml语言
  10. JAVA笔记1-00
  11. Linq to Sql 左连接查询
  12. RandomAccessFile多线程下载、复制文件、超大文件读写
  13. 需求分析---NABCD
  14. sql sever insert into混合嵌套插入
  15. 大规模使用 Apache Kafka 的20个最佳实践
  16. 关于Windows系统不会变慢的设想
  17. Grok patterns 汇总
  18. shell中括号的特殊用法 linux if多条件判断
  19. itcast-spring
  20. svn cleanup

热门文章

  1. [JAVA]使用字节流拷贝文件
  2. input函数报错&quot;*** is not defined&quot;
  3. scala 数据结构(十一):流 Stream、视图 View、线程安全的集合、并行集合
  4. 数据可视化之powerBI技巧(八)Power BI按多列排序的技巧
  5. bzoj3858Number Transformation*
  6. Oracle基础概述
  7. js:数组(创建、遍历、函数)
  8. Intelij DataGrip 的安装和使用
  9. vector基本用法
  10. 附002.Nginx代理相关模块解析