树状数组

特点和用途

  1. 一种数据结构
  2. 快速前缀和
  3. 快速修改某一个数字
  4. 上述两个操作可以动态进行
  5. 两个操作都是 $O(\log N)$

实现

由于本人是Java选手,因此使用Java实现

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

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Solution {

static int max(int... a) {
int res = a[0];
for (int i : a) res = Math.max(res, i);
return res;
}

static int min(int... a) {
int res = a[0];
for (int i : a) res = Math.min(res, i);
return res;
}

static class Read {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stringTokenizer = new StringTokenizer("");

String next() {
while (!stringTokenizer.hasMoreTokens()) {
try {
stringTokenizer = new StringTokenizer(bufferedReader.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return stringTokenizer.nextToken();
}

int nextInt() {return Integer.parseInt(next());}
long nextLong() {return Long.parseLong(next());}
}

static Read in = new Read();
static final int N = (int)(1e5);
static int[] a = new int[N], tr = new int[N];
static int n, m, q;

static int lowbit(int x) {
return x & -x;
}

static void update (int x, int c) {
for (int i = x; i <= n; i += lowbit(i)) tr[i] += c;
}

static int query (int x) {
int res = 0;
for (int i = x; i > 0; i -= lowbit(i)) res += tr[i];
return res;
}

static void init() {
for (int i = 1; i <= n; i++) update(i, a[i]);
}

public static void main(String[] args) {
n = in.nextInt();
for (int i = 1; i <= n; i++) a[i] = in.nextInt();
init();
m = in.nextInt();
while (m-- > 0) {
q = in.nextInt();
if (q == 0) {
int k = in.nextInt();
System.out.println(query(k));
} else if (q == 1) {
int p = in.nextInt(), c = in.nextInt();
update(p, c);
}
}
}
}