1 #define MAXSIZE 50010
2
3 int tree[4*MAXSIZE]; // 此处要开4倍空间
4 int lz[4*MAXSIZE];
5
6 void init()
7 {
8 memset(tree, 0, sizeof(tree));
9 memset(lz, 0, sizeof(lz));
10 }
11
12
13 void build(int node, int l, int r)
14 {
15 if(l == r) // 到达叶子节点,赋值
16 {
17 scanf("%d", &tree[node]);
18 return;
19 }
20
21 int mid = (l+r)/2;
22 build(node*2, l, mid);
23 build(node*2+1, mid+1, r);
24
25 tree[node] = tree[node*2] + tree[node*2+1];
26 }
27
28
29 void push_down(int node, int l, int r)
30 {
31 if(lz[node])
32 {
33 int mid = (l+r)/2;
34 lz[node*2] += lz[node];
35 lz[node*2+1] += lz[node];
36 tree[node*2] += (mid-l+1)*lz[node];
37 tree[node*2+1] += (r-mid)*lz[node];
38 lz[node] = 0;
39 }
40 }
41
42 // 单点更新,node为1(从根开始),lr为根的范围,index为待更新的数,add为更新的增量
43 void update(int node, int l, int r, int index, int add)
44 {
45 if(l == r)
46 {
47 tree[node] += add; // 更新方式
48 return;
49 }
50
51 int mid = (l+r)/2;
52 if(index <= mid) // 进入左子树
53 update(node*2, l, mid, index, add);
54 else // 进入右子树
55 update(node*2+1, mid+1, r, index, add);
56
57 tree[node] = tree[node*2] + tree[node*2 + 1];
58 }
59
60 // 区间更新,lr为更新范围,LR为线段树范围,add为更新值
61 void update_range(int node, int l, int r, int L, int R, int add)
62 {
63 if(l <= L && r >= R)
64 {
65 lz[node] += add;
66 tree[node] += (R-L+1)*add; // 更新方式
67 return;
68 }
69
70 push_down(node, L, R);
71 int mid = (L+R)/2;
72 if(mid >= l) // 进入左子树
73 update_range(node*2, l, r, L, mid, add);
74 if(r > mid) // 进入右子树
75 update_range(node*2+1, l, r, mid+1, R, add);
76
77 tree[node] = tree[node*2] + tree[node*2 + 1];
78 }
79
80 // 区间查找
81 int query_range(int node, int l, int r, int L, int R)
82 {
83 if(l <= L && r >= R)
84 return tree[node];
85 push_down(node, L, R);
86 int mid = (L+R)/2;
87 int sum = 0;
88 if(mid >= l)
89 sum += query_range(node*2, l, r, L, mid);
90 if(r > mid)
91 sum += query_range(node*2+1, l, r, mid+1, R);
92
93 return sum;
94 }