-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSegmentTree.java
72 lines (63 loc) · 3.11 KB
/
SegmentTree.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
package SegmentTree;
import java.util.*;
import java.util.stream.Collectors;
public class SegmentTree {
private Double[] arrayOfSums;
public SegmentTree(List<? extends Number> list){
arrayOfSums = new Double[list.size() * 4];
CreateSegmentsTree(list.stream().map(Number::doubleValue).collect(Collectors.toList()), 1);
}
public SegmentTree(Number[] array) {
arrayOfSums = new Double[array.length * 4];
CreateSegmentsTree(Arrays.stream(array).map(Number::doubleValue).collect(Collectors.toList()), 1);
}
private double CreateSegmentsTree(List<Double> subList, int index) {
if (subList.size() == 1) {
return arrayOfSums[index] = subList.get(0);
}
int size = subList.size();
double leftSubArray = CreateSegmentsTree(subList.subList(0, size / 2), index * 2);
double rightSubArray = CreateSegmentsTree(subList.subList(size / 2, size), index * 2 + 1);
return arrayOfSums[index] = leftSubArray + rightSubArray;
}
public double getSum(int leftBound, int rightBound) {
if (leftBound > rightBound) {
throw new IllegalArgumentException("the left bound is bigger than the right one");
}
return FindSumOfSegment(leftBound, rightBound, 0, arrayOfSums.length / 4 - 1, 1);
}
private double FindSumOfSegment(int leftBound, int rightBound, int leftPosition, int rightPosition, int index) {
if (leftBound == leftPosition && rightBound == rightPosition) {
return arrayOfSums[index];
}
int centrePosition = (leftPosition + rightPosition + 1) / 2;
if (leftBound >= centrePosition) {
return FindSumOfSegment(leftBound, rightBound, centrePosition, rightPosition, index * 2 + 1);
}
if (rightBound < centrePosition) {
return FindSumOfSegment(leftBound, rightBound, leftPosition, centrePosition - 1, index * 2);
}
return FindSumOfSegment(leftBound, centrePosition - 1, leftPosition, centrePosition - 1, index * 2)
+ FindSumOfSegment(centrePosition, rightBound, centrePosition, rightPosition, index * 2 + 1);
}
private double changeValue(int position, double value, int leftPosition, int rightPosition, int index) {
if (leftPosition == rightPosition) {
return arrayOfSums[index] - (arrayOfSums[index] = value);
}
int centrePosition = (leftPosition + rightPosition + 1) / 2;
double difference;
if (position < centrePosition) {
difference = changeValue(position, value, leftPosition, centrePosition - 1, index * 2);
} else {
difference = changeValue(position, value, centrePosition, rightPosition, index * 2 + 1);
}
arrayOfSums[index] -= difference;
return difference;
}
public void set(int index, double value) {
if (index + 1 > arrayOfSums.length / 4) {
throw new IllegalArgumentException("Index out of range!");
}
changeValue(index, value, 0, arrayOfSums.length / 4 - 1, 1);
}
}