文章目录
- Question
- Ideas
- Code
Question
给定 n 个数组成的一个数列,规定有两种操作,一是修改某个元素,二是求子数列 [a,b] 的连续和。
输入格式
第一行包含两个整数 n 和 m,分别表示数的个数和操作次数。
第二行包含 n 个整数,表示完整数列。
接下来 m 行,每行包含三个整数 k,a,b (k=0,表示求子数列[a,b]的和;k=1,表示第 a 个数加 b)。
数列从 1 开始计数。
输出格式
输出若干行数字,表示 k=0 时,对应的子数列 [a,b] 的连续和。
数据范围
1≤n≤100000,
1≤m≤100000,
1≤a≤b≤n,
数据保证在任何时候,数列中所有元素之和均在 int 范围内。
输入样例:
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
Ideas
Code
class Node:
def __init__(self):
self.l, self.r, self.sum = 0, 0, 0
# 利用左右孩子求节点
def pushup(u):
tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum
# 初始化线段树
def build(u, l, r):
if l == r:
tr[u].l, tr[u].r, tr[u].sum = l, r, lis[r]
else:
tr[u].l, tr[u].r = l, r
mid = l + r >> 1
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r)
pushup(u)
# 求[l,r]和
def query(u, l, r):
if tr[u].l >= l and tr[u].r <= r: return tr[u].sum
mid = tr[u].l + tr[u].r >> 1
sum = 0
if l <= mid: sum = query(u << 1, l, r)
if r > mid: sum += query(u << 1 | 1, l, r)
return sum
# x位置加上v
def modify(u, x, v):
if tr[u].l == tr[u].r:
tr[u].sum += v
else:
mid = tr[u].l + tr[u].r >> 1
if x <= mid:
modify(u << 1, x, v)
else:
modify(u << 1 | 1, x, v)
pushup(u)
n, m = map(int, input().split())
lis = [0 for i in range(n + 2)]
lis[1:] = list(map(int, input().split()))
tr = [Node() for i in range(4 * n + 5)]
build(1, 1, n)
for _ in range(m):
k, a, b = map(int, input().split())
if k == 0:
print(query(1, a, b))
else:
modify(1, a, b)