#sZSZybttg040101. 1535:【例 1】数列操作

1535:【例 1】数列操作

好的,我将这道题整理为清晰的题面格式,并补充样例解释、数据范围与时空限制:


题目描述

给定一个包含 nn 个数的数列,规定有两种操作:

  1. 修改某个元素:将第 aa 个数加上 bb(即 A[a]A[a]+bA[a] \gets A[a] + b);
  2. 查询区间和:求子数列 [a,b][a, b] 的连续和(即 i=abA[i]\sum_{i=a}^{b} A[i])。

数列元素个数最多 1010 万个,询问操作最多 1010 万次。


输入格式

  • 第一行两个整数 n,mn, mnn 表示数列长度,mm 表示操作次数);
  • 第二行 nn 个整数,表示初始数列;
  • 接下来 mm 行,每行三个整数 k,a,bk, a, b
    • k=0k=0,表示查询区间 [a,b][a,b] 的和;
    • k=1k=1,表示将第 aa 个数加上 bb

输出格式

对于每个 k=0k=0 的操作,输出一行,表示对应子数列 [a,b][a,b] 的连续和。


样例

样例输入

10 5
1 2 3 4 5 6 7 8 9 10
1 1 5
0 1 3
0 4 8
1 7 5
0 4 8

样例输出

11
30
35

样例解释

初始数列:[1,2,3,4,5,6,7,8,9,10][1,2,3,4,5,6,7,8,9,10]

操作 1:1 1 5 → 将第 11 个数加 55,数列变为 [6,2,3,4,5,6,7,8,9,10][6,2,3,4,5,6,7,8,9,10]
操作 2:0 1 3 → 查询 [1,3][1,3] 的和 =6+2+3=11=6+2+3=11
操作 3:0 4 8 → 查询 [4,8][4,8] 的和 =4+5+6+7+8=30=4+5+6+7+8=30
操作 4:1 7 5 → 将第 77 个数加 55,数列变为 [6,2,3,4,5,6,12,8,9,10][6,2,3,4,5,6,12,8,9,10]
操作 5:0 4 8 → 查询 [4,8][4,8] 的和 =4+5+6+12+8=35=4+5+6+12+8=35


数据范围

  • 1n1051 \le n \le 10^5
  • 1m1051 \le m \le 10^5
  • 数列元素和操作增加值在 int 范围内,但求和可能超出 int,建议使用 long long。

时空限制

  • 时间:1000 ms1000 \text{ ms}
  • 内存:262144 KB262144 \text{ KB}(256 MB)

提示
此题为 单点修改、区间查询 的经典问题,可以用 树状数组(Fenwick Tree)线段树(Segment Tree) 解决。

方法一:树状数组(推荐,代码简洁、常数小):

  • 初始化 treetree 数组;
  • 单点更新:add(pos, delta)
  • 前缀和查询:sum(pos)
  • 区间和:sum(r) - sum(l-1)

复杂度:每次操作 O(logn)O(\log n)

方法二:线段树

  • 构建线段树,每个节点维护区间和;
  • 单点修改:递归更新叶子节点并更新父节点;
  • 区间查询:递归查询区间和。

复杂度:每次操作 O(logn)O(\log n)

注意

  • 输入输出量较大,建议使用 scanf/printf 或关闭同步的 cin/cout
  • 使用 long long 存储区间和,避免溢出。