前缀和——(1)什么是前缀和和一维前缀和

前缀和——(1)什么是前缀和和一维前缀和什么是前缀和前缀和 PrefixSum 的定义为 对于一个给定的数列 A 它的前缀和数列 S 是通过递推能求出来得部分和 例如 C 实现 假设数组 a 和前缀和数组 s 都已经定义 inti 初始条件 a 0 0 s 0 0 for i 1 i lt n i cin gt gt a i s i s

什么是前缀和

前缀和(Prefix Sum)的定义为:对于一个给定的数列 A, 它的前缀和数列 S 是通过递推能求出来得 S[i] = \sum_{j = 1}^{i}A[j]  部分和。

例如:

A[5, 6, 7, 8] = PrefixSum[5, 11, 18, 26]\\ PrefixSum[0] = A[0]\\ PrefixSum[1] = A[0] + A[1]\\ PrefixSum[2] = A[0] + A[1] + A[2]\\ PrefixSum[3] = A[0] + A[1] + A[2] + A[3]\\ ...\\ PrefixSum[n] = A[0] + A[1] + A[2] + A[3] + ... + A[n]

C++实现

//假设数组a和前缀和数组s都已经定义 int i; //初始条件 a[0] = 0; s[0] = 0; for (i=1; i<=n; i++) { cin >> a[i]; s[i] = s[i-1] + a[i]; }

模板题

下面我们用一个模板题,将完整的一维数组前缀和做一个简单的展示。题目链接http://47.110.135.197/problem.php?id=5181。

#include 
  
    using namespace std; int main() { int n; cin >> n; int data; int ans[102] = {}; for (int i=1; i<=n; i++) { cin >> data; ans[i] = ans[i-1] + data; } for (int i=1; i<=n; i++) { cout << ans[i] << " "; } cout << endl; return 0; } 
  

用途

前缀和是一种重要的预处理,能大大降低查询的时间复杂度。

前缀和是以求和的方式灵活地面对区间询问。

下面我们用一个模板题来说明。

例题:区间求和

给你一串长度为 n 的数列 a1, a2, a3, …, an,再给出 m 个询问,每次询问给出 L, R 两个数,要求给出区间 [L, R] 里的数的和。

详细可以参看http://47.110.135.197/problem.php?id=5139。

题目分析

题目非常简单,我们也可以得到一个最简单的解法,暴力操作。也就是对应每个询问,我们都从 L 开始到 R 结束对这个区间的数据进行求和。基本的代码如下:

#include 
  
    using namespace std; const int MAXN = 1e5+2; long long arr[MAXN] = {}; int main() { int n; cin >> n; int i, j; for (i=1; i<=n; i++) { cin >> arr[i]; } int m; int l, r; long long ans = 0; cin >> m; for (i=0; i 
   
     > l >> r; ans = 0; for (j=l; j<=r; j++) { ans += arr[j]; } cout << ans << endl; } return 0; } 
    
  

代码分析

从上面的代码非常明确的分析出来,代码的时间复杂度为 O(n * m)。也就是说,在比赛中这样的解法能否 AC,那就要看数据的量了。当然我们都知道这样的解法,比赛中是肯定不可能 AC。因此唯一的可能就是降低时间复杂度。方法就是使用前缀和。

我们先看前缀和的数学。数列A中某个下标区间 [l, r] 内的数的和定义为:

sum[l, r] = \sum_{i = l}^{r}A[i]\\ = a[l] + a[l+1] + \cdots + a[r]\\ = S[r] - S[l-1]

从上面推导,我们可以清晰的看出,前缀和和区间和的关系。

代码改进

#include 
  
    using namespace std; const int MAXN = 1e5+2; long long arr[MAXN] = {}; long long sum[MAXN] = {}; int main() { int n; cin >> n; int i, j; for (i=1; i<=n; i++) { cin >> arr[i]; sum[i] = sum[i-1] + arr[i]; } int m; int l, r; cin >> m; for (i=0; i 
   
     > l >> r; cout << sum[r] - sum[l-1] << endl; } return 0; } 
    
  

代码分析

从上面的代码非常明确的分析出来,代码的时间复杂度为 O(n)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/229738.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午4:00
下一篇 2026年3月16日 下午4:00


相关推荐

  • linux防火墙_专业的linux web应用防火墙国内排名推荐「建议收藏」

    linux防火墙_专业的linux web应用防火墙国内排名推荐「建议收藏」对于站长来说,网站的安全维护管理是重中之重,但是在建站后我们发现,再配置齐全的网站也会遭遇各种攻击扫描.这时候你就感觉服务器是一个裸奔的鸡蛋,惯性思维会想和普通电脑一样安装防护软件,这里需要注意了,很多方面不是应该就要做,而需要方法和技巧.我们先简单说下,对于网站防火墙,有两种形式:第一种是服务器提供商的硬件防火墙,购买大厂商云服务器,比如阿里云,百度云等都有专业级的硬件防火墙,能够防护加入云厂…

    2022年6月2日
    69
  • java项目中的classpath到底指向的哪里[通俗易懂]

    今天在项目里看到好多地方都用到了类路径,并且自己对路径还不是很清楚,所以就在网上百度了一下!上面图片的意思简单来说,就是classpath只能表示lib目录和WEB-inf/classes路径下的文件,calsspath不能表示的src路径下面的文件,但是从项目结构来看,配置文件一般是不放在放在WEB-INF下面啊,并且也没有看到classes路径,lib目录不是放依赖ja…

    2022年4月4日
    118
  • pytest-allure_苹果11验机报告

    pytest-allure_苹果11验机报告前言allure是一个report框架,支持java的Junit/testng等框架,当然也可以支持python的pytest框架,也可以集成到Jenkins上展示高大上的报告界面。mac环境:

    2022年7月28日
    9
  • 腾讯,大动作!

    腾讯,大动作!

    2026年3月12日
    2
  • 苹果关闭自动更新_iOS屏蔽更新不用描述文件,苹果官方:安排![通俗易懂]

    他来了!他来了!我们可以看到iOS13.6系统测试版在设置里添加了一个关闭自动下载和自动安装的按钮。左:iOS13.5.1右:iOS13.6苹果手机的iOS系统小版本更新不断,老是自动下载更新包,让人感到被强迫升级,即使苹果公司的出发点是好的,“这是为你们好,最新系统更安全”。然而大多数用户都认为没必要经常升级系统,不升级就不会遇到系统Bug,经常升级难免会遇到。有一种…

    2022年4月15日
    216
  • python显示当前日期时间_python获取当前日期和时间的方法

    python显示当前日期时间_python获取当前日期和时间的方法本文实例讲述了 python 获取当前日期和时间的方法 分享给大家供大家参考 具体如下 importdateti Getadatetime datetime datetime now Generalfunct Year d now yearprint Month d now monthprint Day d

    2026年3月19日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号