一维前缀和

2021-10-23 常用算法 前缀和

# 一、算法思想

前缀和定义:Si=a1+a2+⋯aiS_i = a_1 + a_2 + \cdots a_i。

注意

前缀和下标 SiS_i 要从 11 开始,从而避免处理边界情况,统一计算 SiS_i。

# 1.1 计算方法

Si=Si−1+aiS_i = S_{i-1} + a_i

# 1.2 作用

O(1)O(1) 时间内计算区间 [l,r][l,r] 内的元素的和:

al+⋯ar=Sr−Sl−1a_l + \cdots a_r = S_r - S_{l - 1}

# 二、算法模板

Go

type PrefixSum1D struct {
    sum []int
}

// NewPrefixSum1D 初始化一维前缀和
func NewPrefixSum1D(q []int) *PrefixSum1D {
    n := len(q)
    sum := make([]int, n+1)
    for i := 1; i <= n; i++ {
        sum[i] = sum[i-1] + q[i-1]
    }
    return &PrefixSum1D{sum: sum}
}

// 查询一维前缀和
func (ps *PrefixSum1D) query(l, r int) int {
    return ps.sum[r] - ps.sum[l-1]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 三、代码实战

# AcWing 0795


题目:前缀和

输入一个长度为 nn 的整数序列。

接下来再输入 mm 个询问,每个询问输入一对 l,rl,r。

对于每个询问,输出原序列中从第 ll 个数到第 rr 个数的和。

输入格式

第一行包含两个整数 nn 和 mm。

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

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

输出格式

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

数据范围

1≤l≤r≤n1 \le l \le r \le n
1≤n,m≤1051 \le n,\ m \le 10^5
−1000≤数列中元素的值≤1000-1000 \le \text{数列中元素的值} \le 1000

输入样例:

5 3

2 1 3 6 4

1 2

1 3

2 4

输出样例:

3

6

10

解答代码:

    Last Updated: 2023-01-28 4:31:25