”一维前缀和“算法原理及模板

前缀和,就是通过一种方法来求出数组中某个连续区间的元素的和的办法。我们通常先预处理出来一个前缀和数组,然后把数组中进行元素填充后再进行后续使用。

我们通过一道模板题或许能更加理解其意思。

现在的问题就是:如果我们用暴力枚举来记录每次l与r之间的和,那么肯定是会超时的(时间复杂度O(N*q)),我们要另辟蹊径。我们用一下上面的前缀和算法。

假设我们原有的数组为arr,现在我们要另创建一个数组dp。这个dp数组的每一个元素dpi记录着arri及之前的元素之和。

注意,我们这里的arr和dp中的i都是以1开始记录而不是0,稍后我们解释一下原因,我们先把arr0和dp0都看成0。dp中的元素计算公式为:

dpi=dpi-1+arri;

利用这个公式,我们也可以把dp数组进行初始化。接下来就是如何使用,

假设我们要求l-r的和,只需要用dpr-dpl-1即可。

通过这个公式我们就可以说明为什么下标需要从1开始了,如果l为0,也就是想求从最左到r,那么公式里就是dpr-dp-1。越界是万万不可的。所以我们要把arr和dp的0位置空出来并标记为0即可(0并不影响求和)。这种方法我们就成功把时间复杂度变成了o(q)+o(n)。

我们把题解写一下,(代码过程基本就是模板)

cpp 复制代码
#include <iostream>
#include <vector>
 
using namespace std;

int main()
{

   int n,q;
  cin >>n>>q;
  //创建一个n+1个数大小的vector (0-n)
  vector <int>arr (n+1);
  for(int i=1;i<n+1;i++) cin>>arr[i];
 //创建前缀和数组
 vector<long long> dp(n+1);
  for(int i=1;i<n+1;i++) dp[i]=dp[i-1]+arr[i];

  //使用前缀和
   int l=0,r=0;
  while(q--)
 {
    cin>>l>>r;
    cout<<dp[r]-dp[l-1]<<endl;
 }
 return 0;
}

 
    
相关推荐
徐小夕9 小时前
Loop Engineering 深度解析与实战指南(全网最全)
前端·算法·github
北域码匠10 小时前
SHA-1算法:安全哈希原理与应用解析
算法·c#·哈希算法
手写码匠10 小时前
手写 GraphRAG:从零实现图增强检索增强生成系统
人工智能·深度学习·算法·aigc
BomanGe110 小时前
NSK重载高刚性滚珠丝杠技术详解
经验分享·算法·规格说明书
Matrix_1111 小时前
手机里的计算摄影:广角形变校正算法
人工智能·算法·智能手机·计算摄影
WBluuue11 小时前
数据结构与算法:有序表(二):跳表
数据结构·c++·算法·skiplist
不好听61313 小时前
深入理解链表:线性数据结构的另一面
javascript·数据结构
x1387028595713 小时前
c语言中srtlen(指针使用计算字符长度)、传值和传址调用
c语言·开发语言·算法·visual studio
海兰13 小时前
【实用程序】电商销售分析仪表盘 — 从零搭建一个AI参与的全栈数据洞察系统
人工智能·学习·算法
zwenqiyu13 小时前
P5283 [十二省联考 2019] 异或粽子题解
c++·学习·算法