当前位置:首页 > 趣味小程序 > 正文内容

【算法】前缀和与差分(1)一维数组前缀和

亿万年的星光2年前 (2022-07-16)趣味小程序21387

一、定义

前缀和:是指某序列的前n项和。可以理解成数学上上的数列的前n项和。

差分:是前缀和的逆运算。


二、前缀和的分类

可以分成一维数组的前缀和和二维 数组的前缀和

  • 一维数组前缀和

    定义式:

        

 递推式:

    

  • 二维数组前缀和


定义式:

递推式:

    

三、解决什么问题

前缀和、差分是为了解决某一类问题。比如下面这道题目:

【题目描述】

输入一个长度为n的整数序列。接下来再输入M次询问,每个询问输入一对L, R。对于每次询问,输出原序列中从第L个数到第R个数的和。

【输入描述】

第一行包含两个整数n和m。

第二行包含n个整数,表示整数数列。

接下来m行,每行包含两个整数l和r,表示一个询问的区间范围。

【输出描述】

共m行,每行输出一个询问的结果。

【样例输入】

5 3
2 1 3 6 4
1 2
1 3
2 4

【样例输出】

3
6
10

【数据范围】

1≤l≤r≤n,
1≤n,m≤100000,
−1000≤数列中元素的值≤1000

看到这个题目可能很多人会想到暴力求解方法,比如下面这样:

#include<iostream>
using namespace std;
int main(){
    int n,m,sum=0;
    int a[100]; 
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    //暴力求解
    while(m--){
        int L,R;
        int sum=0;
        cin>>L>>R;
        for(int i=L;i<=R;i++){
            sum+=a[i];
        }
        cout<<"sum="<<sum<<endl;  
    }
  
    return 0;
}


按照上面这样做的时间复杂度为O(n*m),如果nm的数据量稍微大一点就很可能超时,如果我们使用前缀和的方法来做的话就能够将时间复杂度降到O(n+m),提高了运算效率,避免超时问题。

 核心代码:

for (int i = 1; i <= n; i ++ ){
	cin >> a[i];
	s[i] = s[i - 1] + a[i];
}

特别是s[i]=s[i-1]+a[i]这行代码,这行代码拆解如下:

s[1]=s[0]+a[1]; //s[0]为0
s[2]=s[1]+a[2]=a[1]+a[2];
s[3]=s[2]+a[3]=a[1]+a[2]+a[3];
s[4]=s[3]+a[4]=a[1]+a[2]+a[3]+a[4];
......

按照上面这样,我们就能得到前缀和了。

我们这么做的优势在于:以O(1)的时间复杂度得到某块区间的总和。

那么,我们求区间和的过程就相对简单了。

因为L<=R, 所以我们可以参考下面的过程:

s[L]=a[1]+a[2]+a[3]+....+a[L]

s[R]=a[1]+a[2]+a[3]+...+a[L]+a[L+1]+a[L+2]+....+a[R]

我们要求的是a[L]+a[L+1]+...+a[R]。也就是s[R]-s[L-1];

然后我们的代码就可以参考下面这样写:

#include<iostream>
using namespace std;
int main(){
    int n,m;
    int a[100]={0};
	int s[100]={0}; 
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        s[i]=s[i-1]+a[i];
    }
    //前缀和 
   	 while (m--){
        int l, r;
        cin >> l >> r;
        cout << s[r] - s[l - 1] << endl;
    }
    return 0;
}


扫描二维码推送至手机访问。

版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

分享给朋友:
返回列表

上一篇:EasyX小游戏—双人反弹球

没有最新的文章了...

相关文章

C++小游戏—猜数游戏

0.游戏内容玩家猜电脑产生的数字,一个两次机会,才对了给提示,猜错减去一次机会。1.参考代码#include<iostream>#include<cstdlib>#includ...

C++ 如何监听用户按下了哪个按键

想做一款小游戏,键盘事件是必须要了解的。前面的文章简单介绍过键盘事件,这篇文章简单实现了监听用户键盘的操作,主要监听“WASD”以及“上下左右”键参考代码#include<cstdio>...

【C++图形化编程】EasyX函数~文字输出相关函数

文字输出相关函数:函数或数据类型描述gettextcolor获取当前文字颜色gettextstyle获取当前字体颜色LOGFONT保存字体样式的结构体outterxtxy指定位置输出字符串drawte...

C++实现弹窗效果

C++实现弹窗效果

1.格式C++实现弹窗效果需要用到messagebox,这个我在C#中用过,C++也有类似用法。messagebox函数,需要引入<windows.h>头文件2.简单用法#include&...

【C++图形化编程】EasyX函数~图像操作相关函数

【C++图形化编程】EasyX函数~图像操作相关函数

图像处理相关函数函数或数据类型描述IMAGE保存图像的对象loadimage读取图片文件saveimage保存绘图内容至图片文件getimage从当前绘图设备种获取图像putimage在当前绘图设备上...

【C++图形化编程】flappy bird(1)—基础框架及图形图像

【C++图形化编程】flappy bird(1)—基础框架及图形图像

0.前言    前面一篇文章,我们简单介绍了鼠标的一些操作, 这篇文章,我们还是一个实战教程,flappy bird的小游戏。1.导入背景和音乐  &...