【贪心】 51nod 1115 最大M字段和 V3

通道

思路:连续上升,连续下降的值放到set里面,然后对于大于m的集合双向链表进行合并,合并肯定是找绝对值最小的合并。

代码:

#include <cstdio>
#include <cstring>
#include <set>
#include <algorithm>
using namespace std;

typedef long long ll;

const int N = 2000005;

ll s[N];
set<pair<ll, int> > a;
int n, m, now;
int pr[N], ne[N];

void Erase(int x) {
    int l = pr[x], r = ne[x];
    ne[l] = r, pr[r] = l;
}
int main() {
    scanf("%d%d", &n, &m);
    ll tem = 0, ans = 0;
    int cnt = 0;
    for(int i = 1, x; i <= n; ++i) {
        scanf("%d", &x);
        if((tem < 0 && x > 0) || (tem > 0 && x < 0)) {
            now += tem > 0;
            s[++cnt] = tem;
            a.insert(make_pair(abs(tem), cnt));
            tem = 0;
        }
        tem += x;
        ans += x > 0 ? x : 0;
    }
    if( ( tem >= 0 && s[1] > 0 ) || ( tem <= 0 && s[1] < 0 ) ) {
       a.erase(make_pair(abs(s[1]),1));
        s[1] += tem;
       a.insert(make_pair(abs(s[1]),1));
    } else {
        now += tem > 0;
        s[++cnt] = tem;
        a.insert( make_pair(abs( tem ), cnt ) );
    }
    for( int i = 1; i <= cnt; ++i ) {
        pr[i] = i - 1, ne[i] = i + 1;
    }
    pr[1] = cnt, ne[cnt] = 1;
    for( ; now > m; --now ) {
        int x = ( *a.begin() ).second;
        a.erase( make_pair(abs(s[x] ), x ) );
        a.erase( make_pair(abs(s[pr[x]] ), pr[x] ) ), a.erase(make_pair(abs( s[ne[x]] ), ne[x] ) );
        ans -= abs( s[x] );
        s[x] = s[x] + s[pr[x]] + s[ne[x]];
        Erase( pr[x] );
        Erase( ne[x] );
        a.insert( make_pair(abs( s[x]), x ) );
    }
    printf( "%I64d\n", ans );
    return 0;
}

时间: 2024-08-08 05:19:43

【贪心】 51nod 1115 最大M字段和 V3的相关文章

51Nod 最大公约数之和V1,V2,V3;最小公倍数之和V1,V2,V3

1040 最大公约数之和 给出一个n,求1-n这n个数,同n的最大公约数的和.比如:n = 6 1,2,3,4,5,6 同6的最大公约数分别为1,2,3,2,1,6,加在一起 = 15 输入 1个数N(N <= 10^9) 输出 公约数之和 输入样例 6 输出样例 15 题解 \[ \sum_{i=1}^n\gcd(i,n)=\sum_{d|n}d\varphi(n) \] 暴力搞就行了. 1188 最大公约数之和 V2 给出一个数N,输出小于等于N的所有数,两两之间的最大公约数之和. 相当于计

【瞎搞】 51nod 1065 最小正字段和

通道 思路:先求一下从第一位开始的到第i位的累加,4,-1,5,-2,-1,2,6,-2 => 4 3 8 6 5 7 13 11 对这个累加的数列排个序,然后只要判断邻近的两个数是否可以组成序列,比如4和3就不可以,因为4 > 3而4对应下标为0,3对应为1.4和5就可以,然后相同的前缀和取id最小,一开始丢个(0,0)进去. 代码: #include <cstdio> #include <cstring> #include <algorithm> usi

【51Nod 1237】最大公约数之和 V3 莫比乌斯反演+杜教筛

题意 求$\sum_{i=1}^{n}\sum_{j=1}^{n}(i,j)$ 枚举约数 $$ \begin{align} ans &=\sum_{d=1}^{n}\sum_{i=1}^{n}\sum_{j=1}^{n}[(i,j)=d] \ &=\sum_{d=1}^{n}\sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{n}{d} \rfloor}[(i,j)=1] \ \end{align} $$ 利用

SNMP简单网络管理协议

声明:以下内容是学习谌玺老师视频整理出来(http://edu.51cto.com/course/course_id-861.html) SNMP(Simple Network Management Protocol,简单网络管理协议),基于TCP/IP工作,能对企业网络中支持SNMP功能的设备进行集中网络管理.这些设备包括服务器.工作站.路由器.交换机.PIX防火墙.ASA.入侵检测与防御设备等,它是一种开放的.标准的应用层协议.SNMP使网络管理员能够更有效的管理企业网络,包括:集中监控网络

51nod 1163 最高的奖励(贪心+优先队列)

题目链接:51nod 1163 最高的奖励 看着这题我立马就想到昨天也做了一道贪心加优先队列的题了奥. 按任务最晚结束时间从小到大排序,依次选择任务,如果该任务最晚结束时间比当前时间点晚,则将该任务的奖励值压入队列,否则将队列中最小的任务的奖励值替换,优先队列按奖励值小的优先. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 using name

51nod贪心算法教程

51nod确实是一个好oj,题目质量不错,wa了还放数据,学习算法来说挺好的,这次我做了几个水的贪心,虽然水,但是确实都很典型. 教程链接:http://www.51nod.com/tutorial/list.html 完美字符串 约翰认为字符串的完美度等于它里面所有字母的完美度之和.每个字母的完美度可以由你来分配,不同字母的完美度不同,分别对应一个1-26之间的整数.   约翰不在乎字母大小写.(也就是说字母F和f)的完美度相同.给定一个字符串,输出它的最大可能的完美度.例如:dad,你可以将

51Nod 1091 线段的重叠(贪心+区间相关,板子题)

1091 线段的重叠 基准时间限制:1 秒 空间限制:131072 KB 分值: 5         难度:1级算法题 X轴上有N条线段,每条线段包括1个起点和终点.线段的重叠是这样来算的,[10 20]和[12 25]的重叠部分为[12 20]. 给出N条线段的起点和终点,从中选出2条线段,这两条线段的重叠部分是最长的.输出这个最长的距离.如果没有重叠,输出0. Input 第1行:线段的数量N(2 <= N <= 50000). 第2 - N + 1行:每行2个数,线段的起点和终点.(0 

X.509 v3 证书字段解释

一, X.509证书是什么? 复杂来说,X.509是由国际电信联盟(ITU-T)制定的数字证书标准.为了提供公用网络用户目录信息服务,ITU于1988年制定了X.500系列标准.其中X.500和X.509是安全认证系统的核心,X.500定义了一种区别命名规则,以命名树来确保用户名称的唯一性:X.509则为X.500用户名称提供了通信实体鉴别机制,并规定了实体鉴别过程中广泛适用的证书语法和数据接口,X.509称之为证书. 简单来说,X.509是一套数字证书的体系标准,它标准化了一个通用的.灵活的证

51nod 1257 背包问题 V3(这不是背包问题是二分)

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1257 题解:不能按照单位价值贪心,不然连样例都过不了 要求的r=sum(x[i]*p[i])/sum(x[i]*w[i])不妨设一个辅助函数 z(l)=sum(x[i]*p[i])-l*sum(x[i]*w[i]), 如果z(l) > 0 即sum(x[i]*p[i])-l*sum(x[i]*w[i])>0-->sum(x[i]*p[i])/sum(