#xDSybttg040301. 1547:【 例 1】区间和

1547:【 例 1】区间和

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


题目描述

给定一个长度为 nn 的数列,初始全部为零。规定有两种操作:

  1. 修改某个元素:将第 aa 个位置的数加上 bb
  2. 求区间连续和:询问区间 [a,b][a, b] 内所有数的和。

请按顺序处理所有操作,并对每个求和操作输出对应的答案。


输入格式

第一行包含两个正整数 n,mn, m (n100000,m500000)(n \le 100000, m \le 500000)

接下来的 mm 行,每行有三个正整数 k,a,bk, a, b (k=0(k=01,a,bn)1, a,b \le n)

  • k=0k=0,表示将第 aa 个位置的数加上 bb
  • k=1k=1,表示询问区间 [a,b][a, b] 内所有数的和。

输出格式

对于每个 k=1k=1 的操作,输出一行一个整数,表示对应区间的和。


样例

样例输入

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

样例输出

10
6
0
6
16
6
24
14
50
41

样例说明

初始数组 [0,0,0,0,0,0,0,0,0,0][0,0,0,0,0,0,0,0,0,0]

逐条操作:

  1. 0 1 10:a[1]+=10a[1]+=10[10,0,0,0,0,0,0,0,0,0][10,0,0,0,0,0,0,0,0,0]
  2. 1 1 4:询问 [1,4][1,4]=10+0+0+0=10=10+0+0+0=10
  3. 0 6 6:a[6]+=6a[6]+=6[10,0,0,0,0,6,0,0,0,0][10,0,0,0,0,6,0,0,0,0]
  4. 1 4 10:询问 [4,10][4,10]=0+0+6+0+0+0+0=6=0+0+6+0+0+0+0=6
  5. 1 8 9:询问 [8,9][8,9]=0+0=0=0+0=0
  6. 1 4 9:询问 [4,9][4,9]=0+0+6+0+0+0=6=0+0+6+0+0+0=6
  7. 0 10 2:a[10]+=2a[10]+=2[10,0,0,0,0,6,0,0,0,2][10,0,0,0,0,6,0,0,0,2]
  8. 1 1 8:询问 [1,8][1,8]=10+0+0+0+0+6+0+0=16=10+0+0+0+0+6+0+0=16
  9. 0 2 10:a[2]+=10a[2]+=10[10,10,0,0,0,6,0,0,0,2][10,10,0,0,0,6,0,0,0,2]
  10. 1 3 9:询问 [3,9][3,9]=0+0+0+6+0+0+0=6=0+0+0+6+0+0+0=6
  11. 0 7 8:a[7]+=8a[7]+=8[10,10,0,0,0,6,8,0,0,2][10,10,0,0,0,6,8,0,0,2]
  12. 0 3 10:a[3]+=10a[3]+=10[10,10,10,0,0,6,8,0,0,2][10,10,10,0,0,6,8,0,0,2]
  13. 0 1 1:a[1]+=1a[1]+=1[11,10,10,0,0,6,8,0,0,2][11,10,10,0,0,6,8,0,0,2]
  14. 1 3 8:询问 [3,8][3,8]=10+0+0+6+8+0=24=10+0+0+6+8+0=24
  15. 1 6 9:询问 [6,9][6,9]=6+8+0+0=14=6+8+0+0=14
  16. 0 5 5:a[5]+=5a[5]+=5[11,10,10,0,5,6,8,0,0,2][11,10,10,0,5,6,8,0,0,2]
  17. 1 1 8:询问 [1,8][1,8]=11+10+10+0+5+6+8+0=50=11+10+10+0+5+6+8+0=50
  18. 0 4 2:a[4]+=2a[4]+=2[11,10,10,2,5,6,8,0,0,2][11,10,10,2,5,6,8,0,0,2]
  19. 1 2 8:询问 [2,8][2,8]=10+10+2+5+6+8+0=41=10+10+2+5+6+8+0=41
  20. 0 1 1:a[1]+=1a[1]+=1[12,10,10,2,5,6,8,0,0,2][12,10,10,2,5,6,8,0,0,2](不影响之前输出)

输出对应第 2,4,5,6,8,10,14,15,17,19 条操作的结果。


数据范围

  • n100000n \le 100000
  • m500000m \le 500000

时空限制

  • 时间:1000 ms1000 \text{ ms}
  • 内存:524288 KB524288 \text{ KB}(512 MB)

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

方法一:树状数组(推荐):

  • 支持单点更新:add(pos, val)
  • 支持前缀和查询:sum(pos)
  • 区间和:sum(r) - sum(l-1)
  • 复杂度:每次操作 O(logn)O(\log n),总复杂度 O(mlogn)O(m \log n),可以接受。

方法二:线段树

  • 节点维护区间和;
  • 单点修改:递归更新叶子节点并更新父节点;
  • 区间查询:递归合并区间和。
  • 复杂度:每次操作 O(logn)O(\log n)

树状数组实现步骤

  1. 初始化数组 tree 大小为 n+1n+1(下标从 1 开始);
  2. 对于每个操作 k a b
    • k=0k=0,执行 add(a, b)
    • k=1k=1,输出 sum(b) - sum(a-1)

注意

  • n105n \le 10^5m5×105m \le 5\times 10^5,输入输出量较大,建议使用 scanf/printf 或关闭同步的 cin/cout
  • 区间求和可能超出 int 范围,建议使用 long long 存储。