Warning: session_start(): open(/var/lib/php/sessions/sess_qi8q0d135s5qlj69a7475ioe7a, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
public class LogNArray extends AbstractList implements RandomAccess {
// Structure is a left-leaning red-black BST, 2-3 version
private static final boolean RED = true;
private static final boolean BLACK = false;
private Node root; // root of the BST
// BST helper node data type
private final static class Node {
private Value val; // associated data
private Node left, right; // links to left and right subtrees
private int sizeAndColor; // subtree count + color (highest bit)
Node() {}
Node(Value val, boolean color, int size) {
this.val = val;
sizeAndColor = size | (color ? 0x80000000 : 0);
}
int size() { return sizeAndColor & 0x7FFFFFFF; }
boolean color() { return sizeAndColor < 0; }
void setSize(int size) { sizeAndColor = sizeAndColor & 0x80000000 | size; }
void setColor(boolean color) { sizeAndColor = size() | (color ? 0x80000000 : 0); }
}
// is node x red; false if x is null ?
private boolean isRed(Node x) {
if (x == null) return false;
return x.color() == RED;
}
// number of node in subtree rooted at x; 0 if x is null
private int size(Node x) {
if (x == null) return 0;
return x.size();
}
public int size() {
return size(root);
}
public boolean isEmpty() {
return root == null;
}
public void add(int idx, Value val) {
if (idx < 0 || idx > size()) throw new IndexOutOfBoundsException(idx + " / " + size());
root = add(root, idx, val);
root.setColor(BLACK);
}
// insert the value pair in index k of subtree rooted at h
private Node add(Node h, int k, Value val) {
if (h == null) return new Node(val, RED, 1);
int t = size(h.left);
if (k < t)
// replace / fit in left child
h.left = add(h.left, k, val);
else if (k == t) {
// move value to right child, replace value
h.right = add(h.right, 0, h.val);
h.val = val;
} else
// replace / fit in right child
h.right = add(h.right, k-t-1, val);
// fix-up any right-leaning links
if (isRed(h.right) && !isRed(h.left)) h = rotateLeft(h);
if (isRed(h.left) && isRed(h.left.left)) h = rotateRight(h);
if (isRed(h.left) && isRed(h.right)) flipColors(h);
h.setSize(size(h.left) + size(h.right) + 1);
return h;
}
public Value remove(int idx) {
Value oldValue = get(idx);
// if both children of root are black, set root to red
if (!isRed(root.left) && !isRed(root.right))
root.setColor(RED);
root = remove(root, idx);
if (root != null) root.setColor(BLACK);
return oldValue;
}
private Node remove(Node h, int k) {
int t = size(h.left);
if (k < t) { // remove from left child
if (!isRed(h.left) && !isRed(h.left.left))
h = moveRedLeft(h);
h.left = remove(h.left, k);
} else { // remove from center or right child
if (isRed(h.left)) {
h = rotateRight(h);
t = size(h.left);
}
if (h.right == null) return null; // drop whole node
if (!isRed(h.right) && !isRed(h.right.left)) {
h = moveRedRight(h);
t = size(h.left);
}
if (k == t) { // replace center value with min of right child
h.val = nodeAtIndex(h.right, 0).val;
h.right = remove(h.right, 0);
}
else h.right = remove(h.right, k-t-1);
}
return balance(h);
}
// make a left-leaning link lean to the right
private Node rotateRight(Node h) {
// assert (h != null) && isRed(h.left);
Node x = h.left;
h.left = x.right;
x.right = h;
x.setColor(x.right.color());
x.right.setColor(RED);
x.setSize(h.size());
h.setSize(size(h.left) + size(h.right) + 1);
return x;
}
// make a right-leaning link lean to the left
private Node rotateLeft(Node h) {
// assert (h != null) && isRed(h.right);
Node x = h.right;
h.right = x.left;
x.left = h;
x.setColor(x.left.color());
x.left.setColor(RED);
x.setSize(h.size());
h.setSize(size(h.left) + size(h.right) + 1);
return x;
}
// flip the colors of a node and its two children
private void flipColors(Node h) {
// h must have opposite color of its two children
// assert (h != null) && (h.left != null) && (h.right != null);
// assert (!isRed(h) && isRed(h.left) && isRed(h.right))
// || (isRed(h) && !isRed(h.left) && !isRed(h.right));
h.setColor(!h.color());
h.left.setColor(!h.left.color());
h.right.setColor(!h.right.color());
}
// Assuming that h is red and both h.left and h.left.left
// are black, make h.left or one of its children red.
private Node moveRedLeft(Node h) {
// assert (h != null);
// assert isRed(h) && !isRed(h.left) && !isRed(h.left.left);
flipColors(h);
if (isRed(h.right.left)) {
h.right = rotateRight(h.right);
h = rotateLeft(h);
flipColors(h);
}
return h;
}
// Assuming that h is red and both h.right and h.right.left
// are black, make h.right or one of its children red.
private Node moveRedRight(Node h) {
// assert (h != null);
// assert isRed(h) && !isRed(h.right) && !isRed(h.right.left);
flipColors(h);
if (isRed(h.left.left)) {
h = rotateRight(h);
flipColors(h);
}
return h;
}
// restore red-black tree invariant
private Node balance(Node h) {
// assert (h != null);
if (isRed(h.right)) h = rotateLeft(h);
if (isRed(h.left) && isRed(h.left.left)) h = rotateRight(h);
if (isRed(h.left) && isRed(h.right)) flipColors(h);
h.setSize(size(h.left) + size(h.right) + 1);
return h;
}
/**
* Returns the height of the BST (for debugging).
* @return the height of the BST (a 1-node tree has height 0)
*/
public int height() {
return height(root);
}
private int height(Node x) {
if (x == null) return -1;
return 1 + Math.max(height(x.left), height(x.right));
}
public Value get(int k) {
return nodeAtIndex(k).val;
}
public Value set(int k, Value val) {
Node n = nodeAtIndex(k);
Value oldValue = n.val;
n.val = val;
return oldValue;
}
public Node nodeAtIndex(int k) {
if (k < 0 || k >= size()) {
throw new IndexOutOfBoundsException(k + " / " + size());
}
return nodeAtIndex(root, k);
}
// the key of rank k in the subtree rooted at x
private Node nodeAtIndex(Node x, int k) {
// assert x != null;
// assert k >= 0 && k < size(x);
int t = size(x.left);
if (t > k) return nodeAtIndex(x.left, k);
else if (t < k) return nodeAtIndex(x.right, k-t-1);
else return x;
}
private boolean check() {
if (!isSizeConsistent()) System.out.println("Subtree counts not consistent");
if (!is23()) System.out.println("Not a 2-3 tree");
if (!isBalanced()) System.out.println("Not balanced");
return isSizeConsistent() && is23() && isBalanced();
}
// are the size fields correct?
private boolean isSizeConsistent() { return isSizeConsistent(root); }
private boolean isSizeConsistent(Node x) {
if (x == null) return true;
if (x.size() != size(x.left) + size(x.right) + 1) return false;
return isSizeConsistent(x.left) && isSizeConsistent(x.right);
}
// Does the tree have no red right links, and at most one (left)
// red links in a row on any path?
private boolean is23() { return is23(root); }
private boolean is23(Node x) {
if (x == null) return true;
if (isRed(x.right)) return false;
if (x != root && isRed(x) && isRed(x.left))
return false;
return is23(x.left) && is23(x.right);
}
// do all paths from root to leaf have same number of black edges?
private boolean isBalanced() {
int black = 0; // number of black links on path from root to min
Node x = root;
while (x != null) {
if (!isRed(x)) black++;
x = x.left;
}
return isBalanced(root, black);
}
// does every path from the root to a leaf have the given number of black links?
private boolean isBalanced(Node x, int black) {
if (x == null) return black == 0;
if (!isRed(x)) black--;
return isBalanced(x.left, black) && isBalanced(x.right, black);
}
public void clear() { root = null; }
}