
前缀和+二分
发布日期:2021-05-07 23:17:50
浏览次数:29
分类:原创文章
本文共 1394 字,大约阅读时间需要 4 分钟。
Powered by:AB_IN 局外人
拿洛谷的一个例子记一下前缀和。
数据超过了1e5,故O(n^2)的算法又行不通,所以换二分
#include<bits/stdc++.h>typedef long long ll;using namespace std;ll n,m,l,r;ll a[1000001],sum[1000001];inline bool check(ll mid){ //用写入和布尔会快一点 int now=0; int cnt=0;//计数器 for(int i=2;i<=n;i++){ if(sum[i]-sum[now]>mid){ //如果i到now的这一段和>mid了,那么计数器+1,重新往右取区间 cnt++; now=i-1; } } return cnt>=m;///如果最后分的区间大于等于了要分的区间,说明mid合法继续二分。}int main(){ cin>>n>>m; cin>>a[1]; sum[1]=a[1]; for(int i=2;i<=n;i++){ //前缀和!!!非常常用 cin>>a[i]; sum[i]=a[i]+sum[i-1]; l=max(l,a[i]);//最小值为整个数组最大的数(因为求的是每段最大和的最小) } r=sum[n];//右边界是前缀和的最大值(即数组的和) while(l<=r){ ///为什么用二分呢?直接遍历也是可以的,但可能会t。二分里有区间的最大值,也有不是区间的最大值,但没关系,总会找到一个最优解,满足分段且最大值最小 ll mid=(l+r)/2;//每个mid都对应了数组一段的和 if(check(mid))//所有的 x'(x'<x)x ′ (x ′ <x) 都是可行解。并且,如果有一个数y是非法解,那么一般的,所有的 y'(y'>y)y ′(y ′>y) 都是非法解。 l=mid+1; else r=mid-1; } cout<<l; return 0;}
完结。
并不!
今天看完清楚姐姐的直播,感觉又明白了许多,赶紧拿一个练练手……
二分+前缀和,太典型了,但是这样反而跑的比较慢。
#include <iostream>typedef long long ll;using namespace std;ll a[2000002],n;int main(){ cin>>n; for(int i=1;i<=n;i++) a[i]+=a[i-1]+i; for(int i=1;i<=n;i++){ //[l,r]的和就是a[r]-a[l-1] ll mid=a[i-1]+n; ll ans=lower_bound(a+1,a+n+1,mid)-a; if(a[ans]-a[i-1]==n){ if(ans!=i) cout<<i<<" "<<ans<<endl; } } return 0;}
奥林oj上跑了668ms, 吸氧+改输入输出跑290ms.
看有大佬用等差数列!?还有公式!
Orz
完结。
发表评论
最新留言
不错!
[***.144.177.141]2025年03月28日 14时10分21秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
自学linux毕业shell面试题
2021-05-08
4 Java 访问控制符号的范围
2021-05-08
第9章 - 有没有替代原因(检验证据)
2021-05-08
VUE3(八)setup与ref函数
2021-05-08
Vue之Element标签页保留用户操作缓存。
2021-05-08
智能合约开发实践(1)
2021-05-08
2. Spring Boot学习——Yaml等配置文件教程
2021-05-08
MATLAB——操作矩阵的常用函数
2021-05-08
CMake自学记录,看完保证你知道CMake怎么玩!!!
2021-05-08
Eigen库中vector.transpose()函数什么意思
2021-05-08
ORB-SLAM2:LocalMapping线程学习随笔【李哈哈:看看总有收获篇】
2021-05-08
ORB-SLAM2:LoopClosing线程学习随笔【李哈哈:看看总有收获篇】
2021-05-08
牛客练习赛56 D 小翔和泰拉瑞亚(线段树)
2021-05-08
hdu6434 Problem I. Count(数论)(好题)
2021-05-08
NC15553 数学考试(线性DP)
2021-05-08
MySQL两阶段提交、崩溃恢复与组提交
2021-05-08