class VEBNode {
private int u;
private int uSquart;
private VEBNode summary;
private VEBNode[] cluster;
private boolean[] element;
private Integer max;
private Integer min;
public VEBNode(int u) {
this.u = u;
if (!isBase()) {
this.uSquart = (int) Math.sqrt(u);
this.summary = new VEBNode(uSquart);
this.cluster = new VEBNode[uSquart];
for (int i = 0; i < uSquart; i++) {
cluster[i] = new VEBNode(uSquart);
}
}
}
public void print(int padding) {
if (isBase()) {
printPadding(padding);println("u: " + u);
printPadding(padding);println("min:" + min);
printPadding(padding);println("max:" + max);
} else {
printPadding(padding);println("u: " + u);
printPadding(padding);println("min:" + min);
printPadding(padding);println("max:" + max);
printPadding(padding);println("summary: ");
summary.print(padding + 4);
printPadding(padding);println("cluster: ");
for (int i = 0; i < uSquart; i++) {
cluster[i].print(padding + 4);
}
}
}
public Integer minimum() {
return this.min;
}
public Integer maximum() {
return this.max;
}
public boolean isMember(int x) {
if (x == min || x == max) {
return true;
} else if(isBase()) {
return false;
} else {
return this.cluster[high(x)].isMember(low(x));
}
}
public Integer successor(int x) {
if (isBase()) {
if (x == 0 && max == 1) {
return 1;
} else {
return null;
}
} else if (min != null && x < min) {
return min;
} else {
Integer maxLow = this.cluster[high(x)].maximum();
if (maxLow != null && low(x) < maxLow) {
Integer offset = cluster[high(x)].successor(low(x));
return index(high(x), offset);
} else {
Integer succCluster = this.summary.successor(high(x));
if (succCluster == null) {
return null;
} else {
Integer offset = this.cluster[succCluster].minimum();
return index(succCluster, offset);
}
}
}
}
public Integer predecessor(int x) {
if (isBase()) {
if (x == 1 && min ==0) {
return 0;
} else {
return null;
}
} else if (max != null && x > max) {
return max;
} else {
Integer minLow = this.cluster[high(x)].minimum();
if (minLow != null && low(x) > minLow) {
Integer offset = cluster[high(x)].predecessor(low(x));
return index(high(x), offset);
} else {
Integer preCluster = this.summary.predecessor(high(x));
if (preCluster == null) {
if (min !=null && x > min) {
return min;
} else {
return null;
}
} else {
Integer offset = this.cluster[preCluster].maximum();
return index(preCluster, offset);
}
}
}
}
public void insert(int x) {
if (min == null) {
empty_tree_insert(this, x);
return;
}
if (x < min) {
Integer t = min;
min = x;
x = min;
}
if (!isBase()) {
if (this.cluster[high(x)].minimum() == null) {
this.summary.insert(high(x));
empty_tree_insert(this.cluster[high(x)], low(x));
} else {
this.cluster[high(x)].insert(low(x));
}
}
if (x > max) {
max = x;
}
}
public void delete(int x) {
if (min == max) {
min = null;
max = null;
} else if (isBase()) {
if (x == 0) {
min = 1;
} else {
min = 0;
}
max = min;
} else {
if (x == min) {
Integer firstCluster = summary.minimum();
x = index(firstCluster, this.cluster[firstCluster].minimum());
min = x;
}
this.cluster[high(x)].delete(low(x));
if (this.cluster[high(x)].minimum() == null) {
this.summary.delete(high(x));
if (x == max) {
Integer summaryMax = this.summary.maximum();
if (summaryMax == null) {
if (summaryMax == null) {
this.max = this.min;
} else {
this.max = index(summaryMax, this.cluster[summaryMax].maximum());
}
}
}
} else if (x == this.max) {
max = index(high(x), this.cluster[high(x)].maximum());
}
}
}
public int index(int cluster, int offset) {
return cluster * uSquart + offset;
}
private void printPadding(int padding) {
for (int i = 0; i < padding; i++) {
System.out.print(' ');
}
}
private void print(Object o) {
System.out.print(o);
}
private void println(Object o) {
System.out.println(o);
}
public boolean isBase() {
return u == 2;
}
public int high(int x) {
return x / uSquart;
}
public int low(int x) {
return x % uSquart;
}
public static void empty_tree_insert(VEBNode v, int x) {
v.min = x;
v.max = x;
}
}
public class VEBTreeTest {
public static void main(String[] args) {
VEBNode node = new VEBNode(16);
node.insert(2);
node.insert(3);
node.insert(4);
node.insert(5);
node.insert(7);
node.insert(14);
node.insert(15);
assert node.minimum() == 2;
assert node.maximum() == 15;
assert node.isMember(2) == true;
assert node.isMember(3) == true;
assert node.isMember(4) == true;
assert node.isMember(5) == true;
assert node.isMember(7) == true;
assert node.isMember(14) == true;
assert node.isMember(15) == true;
assert node.isMember(6) == false;
assert node.successor(2) == 3;
assert node.successor(3) == 4;
assert node.successor(4) == 5;
assert node.successor(5) == 7;
assert node.successor(7) == 14;
assert node.successor(14) == 15;
assert node.successor(15) == null;
assert node.successor(6) == 7;
assert node.predecessor(2) == null;
assert node.predecessor(3) == 2;
assert node.predecessor(4) == 3;
assert node.predecessor(5) == 4;
assert node.predecessor(7) == 5;
assert node.predecessor(14) == 7;
assert node.predecessor(15) == 14;
assert node.predecessor(16) == 15;
node.delete(2);
assert node.minimum() == 3;
assert node.maximum() == 15;
node.delete(15);
assert node.minimum() == 3;
assert node.maximum() == 14;
node.delete(3);
node.delete(4);
node.delete(5);
node.delete(7);
node.delete(14);
assert node.minimum() == null;
assert node.maximum() == null;
}
}