url:Problem - C - Codeforces

题意:

给n个数字和一个m

给一个操作:每次使得其中一个下标的数字 *= -1

要求最后在所有前缀和中前m个数字是最小的

思路:

在所有前缀和中分为三类,一类是在m前面的前缀和,一类是在m后面的前缀和,一类就是m本身

先考虑在m前面的前缀和

如何让在m前面的前缀和全部都>=m前缀和?

直接反过来考虑,从m开始向前面累加,如果累加的值>0了,代表需要操作一次了

因为如果累加值>0了,前面的一个前缀和直接不加这后面的一坨即可 < m前缀和

关于这个思路怎么来的

我借鉴了一下ygg的思路

k为其他前缀和的下标

a[1,k] >= a[1,m] => a[1,k] >= a[1,k] + a[k + 1,m]

所以能得到 a[k + 1,m] <= 0

又因为k >= 1,所以可以得到

任意的 i∈[2,m] 都有a[i,m] <= 0

所以要维护这个性质,就用上面的逆序处理即可

再考虑m后面的前缀和

跟前面的思路类似,对于i∈[m + 1,n]维护a[m + 1,i] >= 0即可

然后就是怎么去实现操作次数最小

直接贪心即可:每次需要操作时从已经遍历的数中取一个最大值/最小值即可

这个性质非常符合优先队列,当然multiset也可以

我用的multiset写的

代码如下:

void solve()
{
int ans = 0;
cin >> n >> m;
vector<int> a(n + 10);
for(int i = 1;i <= n;i++) cin >> a[i];
int res = 0;
multiset<int> s;
for(int i = m;i >= 2;i--)
{
res += a[i];
s.insert(a[i]);
if(res > 0)
{
ans++;
res -= 2 * (*prev(s.end()));
s.erase(prev(s.end()));
}
}
s.clear();
res = 0;
for(int i = m + 1;i <= n;i++)
{
res += a[i];
s.insert(a[i]);
if(res < 0)
{
ans++;
res -= 2 * (*s.begin());
s.erase(s.begin());
}
}
cout << ans << endl;
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

CF1779 Least Prefix Sum的更多相关文章

  1. 4.4 CUDA prefix sum一步一步优化

    1. Prefix Sum 前缀求和由一个二元操作符和一个输入向量组成,虽然名字叫求和,但操作符不一定是加法.先解释一下,以加法为例: 第一行是输入,第二行是对应的输出.可以看到,Output[1] ...

  2. 牛客多校第十场-D- Rikka with Prefix Sum

    链接:https://www.nowcoder.com/acm/contest/148/D来源:牛客网 Prefix Sum is a useful trick in data structure p ...

  3. 牛客网暑期ACM多校训练营(第十场)D Rikka with Prefix Sum (数学)

    Rikka with Prefix Sum 题意: 给出一个数组a,一开始全为0,现在有三种操作: 1.  1 L R W,让区间[L,R]里面的数全都加上W: 2.  2     将a数组变为其前缀 ...

  4. Rikka with Prefix Sum(组合数学)

    Rikka with Prefix Sum 题目描述 Prefix Sum is a useful trick in data structure problems. For example, giv ...

  5. Rikka with Prefix Sum

    Rikka with Prefix Sum 题目 https://www.nowcoder.com/acm/contest/148/D 题目有三个操作 l到r都添加一个数 取一次前缀和 查询区间和 这 ...

  6. Codeforces Round #556 (Div. 2) - C. Prefix Sum Primes(思维)

    Problem  Codeforces Round #556 (Div. 2) - D. Three Religions Time Limit: 1000 mSec Problem Descripti ...

  7. Codeforces 1485F Copy or Prefix Sum

    题目链接 点我跳转 题目大意 给定一个长度为 \(N\) 的序列 \(bi\) 问有多少个长度为 \(N\) 的序列 \(a\) 使得 \(b[i] = a[i]\) 或 \(b[i] = ∑a[j] ...

  8. 牛客网暑期ACM多校训练营(第十场)D Rikka with Prefix Sum (组合数学)

    https://www.nowcoder.com/acm/contest/148/D 题意 一个A数组,初始全为0.现有三种操作,1:给区间[L,R]+w:2:把每个位置的元素变为其前缀和:3:求区间 ...

  9. 2018牛客网暑假ACM多校训练赛(第十场)D Rikka with Prefix Sum 组合数学

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round10-D.html 题目传送门 - https://www.n ...

  10. 牛客多校10 D Rikka with Prefix Sum 不是数据结构

    https://www.nowcoder.com/acm/contest/148/D 题意: 1e5个数,1e5个操作,操作分为: 1.区间加. 2.整个数列替换为前缀和. 3.区间查询. 查询数小于 ...

随机推荐

  1. 原生JavaScript

    原生JavaScript 为了方便查看. 所有的js和css代码都是嵌入式直接写在html代码中 1.js的引入方式 <!DOCTYPE html> <html lang=" ...

  2. 7.MongoDB系列之聚合框架

    1. 管道阶段和可调参数 聚合框架基于管道的概念.他由多个阶段组成,每个阶段都会提供一组按钮或可调参数.每个阶段对其输入执行不同的数据处理任务,并生成文档已作为输出传递到下一阶段. 2. 阶段常见操作 ...

  3. js中通过正则表达式验证邮箱是否合法

    文章目录 1.效果展示 2.问题描述 3.代码实现 1.效果展示 2.问题描述 当用户在输入框输入邮箱后.点击验证邮箱按钮.系统给出提示信息. 3.代码实现 <!DOCTYPE html> ...

  4. 函数柯里化实现sum函数

    需求 实现sum函数,使其可以传入不定长参数,以及不定次数调用 //示例 console.log(sum(1,2)(3)()) //6 console.log(sum(2,3,4,5)(1,2)(3) ...

  5. Dubbo 原理和机制详解 (非常全面)

    Dubbo 是一款Java RPC框架,致力于提供高性能的 RPC 远程服务调用方案.作为主流的微服务框架之一,Dubbo 为开发人员带来了非常多的便利. 大家好,我是 mikechen,专注分享「互 ...

  6. 29.渲染器Renderer

    什么是渲染器     渲染器就是将服务器生成的数据格式转为http请求的格式   渲染器触发及参数配置 在DRF配置参数中,可用的渲染器作为一个类的列表进行定义 但与解析器不同的是,渲染器的列表是有顺 ...

  7. 3.pygame快速入门-游戏循环及动画实现

    游戏循环的开始,意味着游戏的正式开始,游戏循环的作用如下 1.保证游戏不会直接退出 2.变化图像的位置--动画效果 3.检测用户交互--按键.鼠标等     游戏时钟 pyagame提供了一个pyga ...

  8. XAF新手入门 - 前言

    很多小伙伴在第一次接触XAF时,会被它的丰富功能及开箱即用的特点所吸引,即使在不了解XAF的情况下,也能够依葫芦画瓢创建一个功能丰富的应用,但当应用到实际项目中时,你会发现与之前的愿景差距很大,很多都 ...

  9. 聊一聊对一个 C# 商业程序的反反调试

    一:背景 1.讲故事 前段时间有位朋友在微信上找到我,说他对一个商业的 C# 程序用 WinDbg 附加不上去,每次附加之后那个 C# 程序就自动退出了,问一下到底是怎么回事?是不是哪里搞错了,有经验 ...

  10. 虚拟机VMware运行Ubuntu时无法和主机之间复制粘贴的问题

    解决虚拟机VMware运行Ubuntu时无法和主机之间复制粘贴的问题 执行以下命令并重启即可解决 sudo apt-get autoremove open-vm-tools sudo apt-get ...