51nod1053 最大M子段和 V2
$n \leq 50000$的序列,问选不超过$m \leq 50000$个区间使得和最大。
如果正数区间总数比$m$小那肯定全选。否则有两种方式减少区间数量:丢掉一个正区间;补一个负区间连接两个正区间。贪心即可。
先把左右端的负数去掉,然后把正区间和负区间处理出来。优先队列维护区间值,然后开个链表模拟合并(删左右,改自己)。注意删右边时调整右端点。
//#include<iostream>
#include<cstring>
#include<cstdio>
//#include<time.h>
//#include<complex>
//#include<set>
#include<queue>
//#include<vector>
#include<algorithm>
#include<stdlib.h>
using namespace std; #define LL long long
int qread()
{
char c; int s=,f=; while ((c=getchar())<'' || c>'') (c=='-') && (f=-);
do s=s*+c-''; while ((c=getchar())>='' && c<=''); return s*f;
} //Pay attention to '-' , LL and double of qread!!!! int n,m;
#define maxn 50011
#define LL long long LL Abs(LL x) {return x>?x:-x;} int a[maxn]; LL sum[maxn];
int b[maxn],lb,ll[maxn],rr[maxn]; bool vis[maxn];
struct qnode
{
LL v; int id;
bool operator > (const qnode &b) const {return v>b.v;}
};
priority_queue<qnode,vector<qnode>,greater<qnode> > q;
int main()
{
n=qread(); m=qread();
for (int i=;i<=n;i++) a[i]=qread();
{
int L=,R=n; while (a[L]<=) L++; while (a[R]<=) R--;
for (int i=L,j=;i<=R;i++,j++) a[j]=a[i];
n=R-L+; a[n+]=;
}
for (int i=;i<=n;i++) sum[i]=sum[i-]+a[i]; LL ans=;
int cnt=;
{
LL tmp=a[],last=;
for (int i=;i<=n+;i++)
{
if (tmp> && a[i]<=)
{
b[++lb]=last;
q.push((qnode){tmp,lb});
ans+=tmp; cnt++; tmp=a[i]; last=i;
}
else if (tmp> && a[i]>) tmp+=a[i];
else if (tmp<= && a[i]>)
{
b[++lb]=last;
q.push((qnode){-tmp,lb});
tmp=a[i]; last=i;
}
else tmp+=a[i];
}
} for (int i=;i<=lb+;i++) ll[i]=i-,rr[i]=i+; b[lb+]=n+;
if (cnt<=m) {printf("%lld\n",ans); return ;}
while (m<cnt--)
{
while (vis[q.top().id]) q.pop();
ans-=q.top().v; int now=q.top().id; q.pop(); if (ll[now]==)
{
vis[rr[now]]=;
vis[now]=;
int u=rr[now]; ll[rr[now]]=ll[now]; rr[ll[now]]=rr[now];
ll[rr[u]]=ll[u]; rr[ll[u]]=rr[u];
}
else if (rr[now]==lb+)
{
vis[ll[now]]=;
vis[now]=;
int u=ll[now]; ll[rr[now]]=ll[now]; rr[ll[now]]=rr[now];
ll[rr[u]]=ll[u]; rr[ll[u]]=rr[u]; b[lb+]=b[u];
}
else
{
int L=b[ll[now]],R=b[rr[rr[now]]]-;
vis[ll[now]]=; vis[rr[now]]=; int u=ll[now],v=rr[now];
b[now]=L; q.push((qnode){Abs(sum[R]-sum[L-]),now});
ll[rr[u]]=ll[u]; rr[ll[u]]=rr[u];
ll[rr[v]]=ll[v]; rr[ll[v]]=rr[v];
}
} printf("%lld\n",ans);
return ;
}
51nod1053 最大M子段和 V2的更多相关文章
- 51Nod1053 最大M子段和V2 二分+DP
传送门 直接DP的话最多也只能做到\(O(nm)\),对于\(5\times 10^4\)的数据范围实在无能为力 夹克老爷提供的做法是贪心,思想大概是在调整的同时,合理构造每个选择对应的新状态,使得新 ...
- 最大M子段和 V2
51nod1053 这题还是我们熟悉的M子段和,只不过N,M<=50000. 这题似乎是一个堆+链表的题目啊 开始考虑把所有正数负数锁在一起. 比如: 1 2 3 -1 –2 -3 666 缩成 ...
- 51nod 1053 最大M子段和 V2
N个整数组成的序列a[1],a[2],a[3],…,a[n],将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的.如果M >= N个数中正数的个数,那么输出所有正数的和. 例如:-2 ...
- [51nod1254]最大子段和 V2
N个整数组成的序列a[1],a[2],a[3],-,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为 ...
- 51nod 1254 最大子段和 V2 ——单调栈
N个整数组成的序列a[1],a[2],a[3],…,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为 ...
- 51nod 1254 最大子段和 V2
N个整数组成的序列a[1],a[2],a[3],…,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为 ...
- 51nod1524 最大子段和V2
题干 N个整数组成的序列a[1],a[2],a[3],-,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数 ...
- 51nod1254 最大子段和 V2 DP
---题面--- 题解: 表示今天做题一点都不顺.... 这题也是看了题解思路然后自己想转移的. 看的题解其实不是这道题,但是是这道题的加强版,因为那道题允许交换k对数. 因为我们选出的是连续的一段, ...
- 51Nod 最大M子段和系列 V1 V2 V3
前言 \(HE\)沾\(BJ\)的光成功滚回家里了...这堆最大子段和的题抠了半天,然而各位\(dalao\)们都已经去做概率了...先%为敬. 引流之主:老姚的博客 最大M子段和 V1 思路 最简单 ...
随机推荐
- iOS5 and iOS6都只支持横屏的方法
If your app uses a UINavigationController, then you should subclass it and set the class in IB. You ...
- java 中设计模式
1. 单例模式(一个类只有一个实例) package ch.test.notes.designmodel; /** * Description: 单例模式 (饿汉模式 线程安全的) * * @auth ...
- history 路由且带二级目录的Apache配置
有多个项目目录的时候 由于项目不知一个,所以不得不为每一个项目建一个专有的文件夹,这就导致了在配置nginx的时候会出现二级目录 - step1: 修改 vue.config.js 添加配置 ...
- node mocha mochawesome报安装不成功
1.进行cnpm安装: npm install cnpm -g --registry=https://registry.npm.taobao.org 2.查看cnpm版本 cnpm -v 3.安装mo ...
- iOS开发各种证书问题
引言 写在前面 一.App ID(bundle identifier) 二.设备(Device) 三.开发证书(Certificates) 四.供应配置文件(Provisioning ...
- Window命令行杀进程
Window命令行杀进程 1.查看任务列表 tasklist 2.以映象名杀 taskkill -t -f -im xx.exe 3.以进程杀死 taskkill /pid pid号 /f 4.针对w ...
- 将 PROTOCOL 的方法声明为 MUTATING
将 PROTOCOL 的方法声明为 MUTATING 由 王巍 (@ONEVCAT) 发布于 2014/08/17 Swift 的 protocol 不仅可以被 class 类型实现,也适用于 str ...
- 经典的7种排序算法 原理C++实现
排序是编程过程中经常遇到的操作,它在很大程度上影响了程序的执行效率. 7种常见的排序算法大致可以分为两类:第一类是低级排序算法,有选择排序.冒泡排序.插入排序:第二类是高级排序算法,有堆排序.排序树. ...
- 【树形dp 最长链】bzoj1912: [Apio2010]patrol 巡逻
富有思维性的树形dp Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, ...
- python 发送附件
#!/usr/bin/env python # encoding: utf-8 #@author: 东哥加油! #@file: sksendmail.py #@time: 2018/8/20 13:3 ...