首页IT科技p0700变速箱控制系统(CF1779C Least Prefix Sum 题解)

p0700变速箱控制系统(CF1779C Least Prefix Sum 题解)

时间2025-06-13 19:26:58分类IT科技浏览4228
导读:CF链接:Least Prefix Sum Luogu链接:...

CF链接:Least Prefix Sum

Luogu链接:LeastPrefix Sum

$ {\scr \color {CornflowerBlue}{\text{Solution}}} $

先来解释一下题意:

给定一个数组             ,问最少把多少个数变成相反数                    ,使得$ \forall \cal{i}$,$ \sum_{k=1}^i a_k$ $ \le$$\sum_{k=1}^m a_k$

发现对于所有数据点      ,$ \cal{n} \le 2 \times 10^5$      ,说明需要 $ Ο(\cal{n \log n}) $ 或者 $ O(\cal{n}) $的算法             。

分析一下题目                    ,发现要分成$ \cal{i} > \cal{m}$ 与$ \cal{i} < \cal{m}$两种情况分类讨论

当 $\cal{i}$ $ > \cal{m}$时:

什么时候才能使$\sum_{k=1}^i a_k$ $ \le$$\sum_{k=1}^m a_k$ 成立呢?

是不是只要使新加的每一段都小于等于0就行了?($\sum_{k=m}^i a_k$ $ \le$$ 0$)

也很好证明:一个数($\sum_{k=1}^m a_k$)加上一个小于等于0的数($\sum_{k={m+1}}^i a_k$)             ,一定不大于原数                   。

当 $\cal{i}$ $ < \cal{m}$时:

同理      ,只要使后加的每一段都小于等于0就行了($\sum_{k=i}^i a_k$ $ \ge$$ 0$)

也很好证明:一个数($\sum_{k=1}^i a_k$)加上一个大于等于0的数($\sum_{k=i}^m a_k$)                   ,一定不小于原数       。

而且             ,由于这两种情况类似(博主太懒),那就只考虑当 $\cal{i}$ $ > \cal{m}$的情况吧             。

问题已经转化完了                   ,接下来怎么办?

第一眼想到的是贪心                   。

设当前要取第$\cal{i}$个       。

有一个不成熟的贪心:如果目前累加和加上$a_i$还是小于等于$0$的                   ,就加上$a_i$,如果大于$0$了             ,就把$a_i$取反                   ,$ ans+1$      。

Hack数据

我们只要把999 变成-999就行了      ,但如果按上面贪心方法             ,我们要把2                    ,3都改变!

那么贪心就不可以用了吗?

有个神奇的东西交叫反悔贪心!

简单说一下:对于当前不是最优的情况      ,留到后面重新选择                   。

我们肯定要让每次改变值后      ,获得综合最小的值                    ,但当前的选择又不一定最有优             。

我们可以用一个优先队列维护             ,到了每次要改的时候      ,从优先队列中选出一个收益最大(使目前累加和最大或最小)的值修改      。

注意开$ \cal{long long}$并且清空优先队列!

Code(赛时代码                   ,过丑见谅QwQ):

#include<bits/stdc++.h> #define L long long using namespace std; L a[200005]; priority_queue<L,vector<L>,greater<L> > q; int main() { int t; scanf("%d",&t); while(t--) { while(!q.empty()) q.pop(); int n,m,ans=0; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); if(n==1) { printf("0\n"); continue; } if(m==1) { L mu=0; for(int i=m+1;i<=n;i++) { if(a[i]>=0) mu+=a[i]; else if(a[i]<0 && mu+a[i]>=0) { q.push(a[i]); mu+=a[i]; } else { ans++; q.push(a[i]); mu+=a[i]; mu-=2*q.top(); q.pop(); } } printf("%d\n",ans); continue; } L mu=0; for(int i=m+1;i<=n;i++) { if(a[i]>=0) mu+=a[i]; else if(a[i]<0 && mu+a[i]>=0) { q.push(a[i]); mu+=a[i]; } else { ans++; q.push(a[i]); mu+=a[i]; mu-=2*q.top(); q.pop(); } } while(!q.empty()) q.pop(); mu=0; for(int i=m;i>=2;i--) { if(a[i]<=0) mu+=a[i]; else if(a[i]>0 && mu+a[i]<=0) { q.push(-a[i]); mu+=a[i]; } else { ans++; q.push(-a[i]); mu+=a[i]; mu+=2*q.top(); q.pop(); } } printf("%d\n",ans); } return 0; }
声明:本站所有文章             ,如无特殊说明或标注,均为本站原创发布                   。任何个人或组织                   ,在未征得本站同意时                   ,禁止复制             、盗用                   、采集       、发布本站内容到任何网站             、书籍等各类媒体平台             。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
蓬莱SEO技巧诀窍(蓬莱seo窍门方法) 华为新款matex3为什么没货(华为mate x3最新消息)