-
Notifications
You must be signed in to change notification settings - Fork 181
/
Copy pathcode.cpp
120 lines (113 loc) · 3.56 KB
/
code.cpp
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import java.util.Random;
// import visualization libraries {
import org.algorithm_visualizer.*;
// }
class Main {
// define tracer variables {
Array1DTracer inputTracer = new Array1DTracer("Input");
Array1DTracer treeTracer = new Array1DTracer("Tree");
Array1DTracer rangeTracer = new Array1DTracer("Range");
LogTracer logTracer = new LogTracer("Console");
// }
// define input variables
int range[];
int parent[];
int input[];
int tree[];
int n;
// Finds parents for BIT
void findParent(){
for(int i = 1; i < n + 1; i++){
int p = i - (i & -i);
parent[i] = p;
}
}
// Correctly selects par to par + (i & -i)
void selectRange(int i){
int par = parent[i];
for(int ind = par; ind < par + (i & -i); ind++){
rangeTracer.select(ind);
}
}
void update(int val, int index, int n){
index = index + 1;
while(index <= n){
// Show updating of current index
logTracer.println("Currently updating index: " + index);
treeTracer.patch(index, tree[index] + val);
selectRange(index);
Tracer.delay();
// Deselect and delay
for(int i = 0; i < n; i++){
rangeTracer.deselect(i);
}
treeTracer.depatch(index);
Tracer.delay();
tree[index] += val;
index += (index & -index);
}
}
void solve(){
for(int i = 0; i < input.length; i++){
inputTracer.select(i);
logTracer.println("Adding " + input[i] + " to tree");
Tracer.delay();
update(input[i], i, n);
Tracer.delay();
inputTracer.deselect(i);
}
Random gen = new Random();
int left = gen.nextInt(n) + 1;
int right = Math.min(gen.nextInt(n - 1) + left + 1, n - 1);
logTracer.println("Finding sum between: (" + left + ", " + right + ")");
int r = query(right);
int l = query(left - 1);
logTracer.println("Left to right sum is: " + (r - l));
}
int query(int index){
int total = 0;
logTracer.println("Calculating sum for 0 to " + index);
index = index + 1;
while(index >= 1){
logTracer.println("Current total: " + total);
int nextIndex = index - (index & -index);
treeTracer.select(index);
// Select range represented by tree index and deselect afterwards
selectRange(index);
Tracer.delay();
for(int i = 0; i < n; i++){
rangeTracer.deselect(i);
}
total += tree[index];
index = nextIndex;
}
logTracer.println("Total sum is: " + total);
return total;
}
Main() {
// visualize {
Layout.setRoot(new VerticalLayout(new Commander[]{rangeTracer, inputTracer, treeTracer, logTracer}));
Random gen = new Random();
n = gen.nextInt(20) + 5;
// Loads neccessary arrays
input = new int[n];
range = new int[n];
tree = new int[n + 1];
parent = new int[n + 1];
// Calculate parents
findParent();
for(int i = 0; i < n; i++){
input[i] = gen.nextInt(30);
}
inputTracer.set(input);
treeTracer.set(tree);
rangeTracer.set(range);
// treeTracer.set(tree);
// Tracer.delay();
// }
solve();
}
public static void main(String[] args) {
new Main();
}
}