Zth's Blog

记录学习路上的点滴

0%

动态开点线段树与线段树合并

进阶数据结构

动态开点线段树

代码

使用的题目是洛谷树状数组1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <iostream>
#include <cstdio>

int n, m;
int tot, root;
struct Tree
{
int ls, rs;
int dat;
} tr[10000007];

int AddNode()
{
tot ++;

tr[tot].ls = tr[tot].rs = tr[tot].dat = 0;

return tot;
}

void Modify(int rt, int l, int r, int p, int v)
{
if(l == r)
{
tr[rt].dat += v;

return;
}

int mid = (l + r) >> 1;

if(p <= mid)
{
if(! tr[rt].ls) tr[rt].ls = AddNode();

Modify(tr[rt].ls, l, mid, p, v);
}
else
{
if(! tr[rt].rs) tr[rt].rs = AddNode();

Modify(tr[rt].rs, mid + 1, r, p, v);
}

tr[rt].dat = tr[tr[rt].ls].dat + tr[tr[rt].rs].dat;
}

int Query(int rt, int l, int r, int ql, int qr)
{
if(l >= ql && r <= qr) return tr[rt].dat;

int mid = (l + r) >> 1;

int res = 0;
if(ql <= mid)
res += tr[rt].ls ? Query(tr[rt].ls, l, mid, ql, qr) : 0;
if(qr > mid)
res += tr[rt].rs ? Query(tr[rt].rs, mid + 1, r, ql, qr) : 0;

return res;
}

int main()
{
root = AddNode();

scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++)
{
int a;
scanf("%d", &a);

Modify(root, 1, n, i, a);
}
for(int i = 1; i <= m; i ++)
{
int op, x, y;
scanf("%d%d%d", &op, &x, &y);

if(op == 1)
Modify(root, 1, n, x, y);
else
printf("%d\n", Query(root, 1, n, x, y));
}

return 0;
}