前缀和
在学完数组后常会遇见这样的题如B3612【深进1.例1】求区间和:
有n个数,$ a1,a2,a3.....an(ai<=105),m<=103$ ,
你会写出这样的代码:
while(m--){
for(int i=起点;i<=终点;i++)
sum+=a[i];
...............
抛开题目,我们来说一下前缀和优化
有
创建一个
- 得到一个前缀和公式:
得到Code:
#include<iostream>
using namespace std;
int a[9]={0,1,2,3,4,5,6,7,8};
int sum[9];
int main(){
sum[1]=a[1];
for(int i=2;i<=8;i++)
sum[i]=sum[i-1]+a[i];
for(int i=1;i<=8;i++)
cout<<sum[i]<<" ";
return 0;
}
标准前缀和:
#include<iostream>
using namespace std;
long long a[100005],n;
long long sum[100005];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
sum[i]=a[i]+sum[i-1];
}
for(int i=1;i<=n;i++) cout<<sum[i]<<" ";
return 0;
}
回到题目
通过前缀和公式,最早的题目B3612【深进1.例1】求区间和代码如下:
#include<iostream>
using namespace std;
long long a[100005],n,m;
long long sum[100005];
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
sum[i]=a[i]+sum[i-1];
}
for(int i=1;i<=m;i++){
int l,r;
cin>>l>>r;
cout<<sum[r]-sum[l-1];
}
return 0;
}
方法:前缀和
Code:
#include<iostream>
#include<cmath>
using namespace std;
long long a[4000005],n,m;
long long sum[4000005],maxn,mi,mj;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
sum[i]=a[i]+sum[i-1];
}
for(int i=1;i<=n;i++){
int l=i,r=n,mid;
while(l<=r){
mid=(r+l)/2;
if(sum[mid]-sum[i-1]>m) r=mid-1;
else l=mid+1;
}
if(sum[r]-sum[i-1]<=m){
if(sum[r]-sum[i-1]>maxn){
mi=i;
mj=r;
maxn=sum[r]-sum[i-1];
}
}
}
cout<<mi<<" "<<mj<<" "<<maxn;
return 0;
}
本文来自一名初中牲,作者:To_Carpe_Diem
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?