当前位置: 首页 > news >正文

C++算法·前缀和

前缀和(Prefix(Prefix(Prefix Sum)Sum)Sum)的定义

前缀和是一种高效处理区间求和问题的算法技巧
其核心思想是通过预处理构建一个前缀和数组
使得后续的区间和查询可以在常数时间O(1)O(1)O(1)内完成

核心概念

  • 定义
    给定一个数组a[1...n]a[1...n]a[1...n],其前缀和数组s[1...n]s[1...n]s[1...n]定义为:
    s[0]=0(边界条件)s[0]=0(边界条件)s[0]=0(边界条件)
    s[i]=a[1]+a[2]+...+a[i](前i个元素的和)s[i]=a[1]+a[2]+...+a[i](前i个元素的和)s[i]=a[1]+a[2]+...+a[i](i个元素的和)
    通过递推计算:s[i]=s[i−1]+a[i]s[i]=s[i-1]+a[i]s[i]=s[i1]+a[i]
  • 作用
    快速计算区间和:查询a[l...r]a[l...r]a[l...r]的和时,只需计算s[r]−s[l−1]s[r]-s[l-1]s[r]s[l1],无需遍历整个区间。
    优化时间复杂度:
    预处理:O(n)O(n)O(n)
    单次查询:O(1)O(1)O(1)
    适用于频繁查询但数据不频繁修改的场景(如静态数组)

对比其他方法差距/使用前缀和的原因

方法预处理时间单次查询时间适用场景
暴力遍历O(1)O(n)查询极少
前缀和O(n)O(1)查询多,数据静态
线段树/树状数组O(n)O(log n)查询和修改都频繁

总结

前缀和通过空间换时间,将区间和查询优化至O(1)O(1)O(1),是算法竞赛中的常客
若需支持动态修改,可结合差分数组或升级为树状数组/线段树

前缀和代码模板示例

#include<iostream>
using namespace std;
const int N=1e6+10;
int a[N],s[N];
int main(){int n,q;//n=数组个数,q=询问次数cin>>n>>q;for(int i=1;i<=n;i++){cin>>a[i];//读入初值s[i]=s[i-1]+a[i];//计算前缀和}for(int i=1;i<=q;i++){int l,r;//询问区间cin>>l>>r;cout<<s[r]-s[l-1]<<endl;//输出区间和}return 0;
}

原理

非常EasyEasyEasy
前缀和数组s[x]s[x]s[x]的值相当于a[1]a[1]a[1]~a[x]a[x]a[x]
利用这个原理计算得知
a[l]到a[r]的和=s[r]−s[l−1]a[l]到a[r]的和=s[r]-s[l-1]a[l]a[r]的和=s[r]s[l1]

例题

P8218 【深进1.例1】求区间和

题目描述

给定由 nnn 个正整数组成的序列 a1,a2,⋯,ana_1, a_2, \cdots, a_na1,a2,,anmmm 个区间 [li,ri][l_i,r_i][li,ri],分别求这 mmm 个区间的区间和。

输入格式

第一行包含一个正整数 nnn,表示序列的长度。

第二行包含 nnn 个正整数 a1,a2,⋯,ana_1,a_2, \cdots ,a_na1,a2,,an

第三行包含一个正整数 mmm,表示区间的数量。

接下来 mmm 行,每行包含两个正整数 li,ril_i,r_ili,ri,满足 1≤li≤ri≤n1\le l_i\le r_i\le n1lirin

输出格式

mmm 行,其中第 iii 行包含一个正整数,表示第 iii 组答案的询问。

输入输出样例 #1

输入 #1

4
4 3 2 1
2
1 4
2 3

输出 #1

10
5

说明/提示

样例解释

111 到第 444 个数加起来和为 101010。第 222 个数到第 333 个数加起来和为 555

数据范围

对于 50%50 \%50% 的数据:n,m≤1000n,m\le 1000n,m1000

对于 100%100 \%100% 的数据:1≤n,m≤1051 \le n, m\le 10^51n,m1051≤ai≤1041 \le a_i\le 10^41ai104

分析

经典的前缀和例题
看输入要求,输入数组个数nnn
然后给数组a[]a[]a[]初值,再输入询问次数mmm
mmm行的li,ril_i,r_ili,ri并询问a[li]到a[ri]a[l_i]到a[r_i]a[li]a[ri]的区间和
跟模板一样,但是需要把mmm的输入改到输入数组a[]a[]a[]的后方

ACACAC代码

#include<iostream>
using namespace std;
const int N=1e6+10;
int a[N],s[N];
int main(){int n,m;//n=数组个数,m=询问次数cin>>n;for(int i=1;i<=n;i++){cin>>a[i];//读入初值s[i]=s[i-1]+a[i];//计算前缀和}cin>>m;for(int i=1;i<=m;i++){int l,r;//询问区间cin>>l>>r;cout<<s[r]-s[l-1]<<endl;//输出区间和}return 0;
}

题单附送

题单题单题单
包含前缀和、差分、离散化

~ 完结撒花完结撒花完结撒花 ~

附:例题来自洛谷洛谷洛谷
推荐洛谷洛谷洛谷作为为你的刷题区域
下一篇预告:还在找~

http://www.dtcms.com/a/326766.html

相关文章:

  • DCN之AP IGMP Snooping 原理与配置
  • P3917 异或序列 题解
  • Day01_QT编程20250811
  • while循环结合列表或字典
  • 二叉搜索树解析与实现
  • 快速设计简单嵌入式操作系统(3):动手实操,基于STC8编写单任务执行程序,感悟MCU指令的执行过程
  • USB 标准请求
  • 机器学习——KMeans聚类实战案例解析
  • git配置proxy
  • Docker-09.Docker基础-Dockerfile语法
  • Docker中部署安装MySQL 5.7.32的详细过程
  • Rust面试题及详细答案120道(19-26)-- 所有权与借用
  • PTE之路--04文
  • java面试题准备
  • 【k近邻】Kd树的构造与最近邻搜索算法
  • 线程池知识点总结
  • Spring Cloud Gateway 路由与过滤器实战:转发请求并添加自定义请求头(最新版本)
  • 【QT】UI 开发全攻略:打造专业级跨平台界面
  • Android14 QS编辑页面面板的加载解析
  • 梯度裁剪总结
  • Python Day27 HTML 核心知识笔记及例题分析
  • 09-docker镜像手动制作
  • PG靶机 - Flu
  • 常见鱼饵制作方式
  • 在 X86_64(amd64) 平台上的docker支持打包构建多环境镜像并推送镜像到Harbor
  • AI Coding 概述及学习路线图
  • uploader组件,批量上传怎么设置实时滚动
  • Anti-Aliasing/Mip-NeRF/Zip-NeRF/multi-scale representation
  • 2.一维码+二维码+字符识别
  • OpenHarmony概述与使用