好的,我将这道题整理为清晰的题面格式,并补充样例解释、数据范围与时空限制:
题目描述
给定一个长度为 n 的数列,初始全部为零。规定有两种操作:
- 修改某个元素:将第 a 个位置的数加上 b;
- 求区间连续和:询问区间 [a,b] 内所有数的和。
请按顺序处理所有操作,并对每个求和操作输出对应的答案。
输入格式
第一行包含两个正整数 n,m (n≤100000,m≤500000)。
接下来的 m 行,每行有三个正整数 k,a,b (k=0 或 1,a,b≤n):
- 若 k=0,表示将第 a 个位置的数加上 b;
- 若 k=1,表示询问区间 [a,b] 内所有数的和。
输出格式
对于每个 k=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 1 10:a[1]+=10 → [10,0,0,0,0,0,0,0,0,0]
- 1 1 4:询问 [1,4] 和 =10+0+0+0=10
- 0 6 6:a[6]+=6 → [10,0,0,0,0,6,0,0,0,0]
- 1 4 10:询问 [4,10] 和 =0+0+6+0+0+0+0=6
- 1 8 9:询问 [8,9] 和 =0+0=0
- 1 4 9:询问 [4,9] 和 =0+0+6+0+0+0=6
- 0 10 2:a[10]+=2 → [10,0,0,0,0,6,0,0,0,2]
- 1 1 8:询问 [1,8] 和 =10+0+0+0+0+6+0+0=16
- 0 2 10:a[2]+=10 → [10,10,0,0,0,6,0,0,0,2]
- 1 3 9:询问 [3,9] 和 =0+0+0+6+0+0+0=6
- 0 7 8:a[7]+=8 → [10,10,0,0,0,6,8,0,0,2]
- 0 3 10:a[3]+=10 → [10,10,10,0,0,6,8,0,0,2]
- 0 1 1:a[1]+=1 → [11,10,10,0,0,6,8,0,0,2]
- 1 3 8:询问 [3,8] 和 =10+0+0+6+8+0=24
- 1 6 9:询问 [6,9] 和 =6+8+0+0=14
- 0 5 5:a[5]+=5 → [11,10,10,0,5,6,8,0,0,2]
- 1 1 8:询问 [1,8] 和 =11+10+10+0+5+6+8+0=50
- 0 4 2:a[4]+=2 → [11,10,10,2,5,6,8,0,0,2]
- 1 2 8:询问 [2,8] 和 =10+10+2+5+6+8+0=41
- 0 1 1:a[1]+=1 → [12,10,10,2,5,6,8,0,0,2](不影响之前输出)
输出对应第 2,4,5,6,8,10,14,15,17,19 条操作的结果。
数据范围
- n≤100000
- m≤500000
时空限制
- 时间:1000 ms
- 内存:524288 KB(512 MB)
提示
此题为 单点修改、区间求和 的经典问题,可以用 树状数组(Fenwick Tree) 或 线段树(Segment Tree) 解决。
方法一:树状数组(推荐):
- 支持单点更新:
add(pos, val)
- 支持前缀和查询:
sum(pos)
- 区间和:
sum(r) - sum(l-1)
- 复杂度:每次操作 O(logn),总复杂度 O(mlogn),可以接受。
方法二:线段树:
- 节点维护区间和;
- 单点修改:递归更新叶子节点并更新父节点;
- 区间查询:递归合并区间和。
- 复杂度:每次操作 O(logn)。
树状数组实现步骤:
- 初始化数组
tree 大小为 n+1(下标从 1 开始);
- 对于每个操作
k a b:
- 若 k=0,执行
add(a, b);
- 若 k=1,输出
sum(b) - sum(a-1)。
注意:
- n≤105,m≤5×105,输入输出量较大,建议使用
scanf/printf 或关闭同步的 cin/cout;
- 区间求和可能超出 int 范围,建议使用
long long 存储。