class RootishArrayStack(BaseList): def __init__(self, iterable=[]): self._initialize() self.add_all(iterable) def _initialize(self): self.n = 0 self.blocks = ArrayStack() def _i2b(self, i): return int(ceil((-3.0 + sqrt(9 + 8 * i)) / 2.0)) def grow(self): self.blocks.append(new_array(self.blocks.size() + 1)) def shrink(self): r = self.blocks.size() while r > 0 and (r - 2) * (r - 1) / 2 >= self.n: self.blocks.remove(self.blocks.size() - 1) r -= 1 def get(self, i): if i < 0 or i > self.n - 1: raise IndexError() b = self._i2b(i) j = i - b * (b + 1) / 2 return self.blocks.get(b)[j] def set(self, i, x): if i < 0 or i > self.n - 1: raise IndexError() b = self._i2b(i) j = i - b * (b + 1) / 2 y = self.blocks.get(b)[j] self.blocks.get(b)[j] = x return y def add(self, i, x): if i < 0 or i > self.n: raise IndexError() r = self.blocks.size() if r * (r + 1) / 2 < self.n + 1: self.grow() self.n += 1 for j in range(self.n - 1, i, -1): self.set(j, self.get(j - 1)) self.set(i, x) def remove(self, i): if i < 0 or i > self.n - 1: raise IndexError() x = self.get(i) for j in range(i, self.n - 1): self.set(j, self.get(j + 1)) self.n -= 1 r = self.blocks.size() if (r - 2) * (r - 1) / 2 >= self.n: self.shrink() return x def clear(self): self.blocks.clear() self.n = 0
class RootishArrayStack(BaseList): def __init__(self, iterable=[]): self._initialize() self.add_all(iterable) def _initialize(self): self.n = 0 self.blocks = ArrayStack() def _i2b(self, i): return int(ceil((-3.0 + sqrt(9 + 8*i)) / 2.0)) def grow(self): self.blocks.append(new_array(self.blocks.size()+1)) def shrink(self): r = self.blocks.size() while r > 0 and (r-2)*(r-1)/2 >= self.n: self.blocks.remove(self.blocks.size()-1) r -= 1 def get(self, i): if i < 0 or i > self.n - 1: raise IndexError() b = self._i2b(i) j = i - b*(b+1)/2 return self.blocks.get(b)[j] def set(self, i, x): if i < 0 or i > self.n - 1: raise IndexError() b = self._i2b(i) j = i - b*(b+1)/2 y = self.blocks.get(b)[j] self.blocks.get(b)[j] = x return y def add(self, i, x): if i < 0 or i > self.n: raise IndexError() r = self.blocks.size() if r*(r+1)/2 < self.n + 1: self.grow() self.n += 1 for j in range(self.n-1, i, -1): self.set(j, self.get(j-1)) self.set(i, x) def remove(self, i): if i < 0 or i > self.n - 1: raise IndexError() x = self.get(i) for j in range(i, self.n-1): self.set(j, self.get(j+1)) self.n -= 1 r = self.blocks.size() if (r-2)*(r-1)/2 >= self.n: self.shrink() return x def clear(self): self.blocks.clear() n = 0
class DualArrayDeque(BaseList): def __init__(self, iterable=[]): self._initialize() self.add_all(iterable) def _initialize(self): self.front = ArrayStack() self.back = ArrayStack() def get(self, i): if i < self.front.size(): return self.front.get(self.front.size() - i - 1) else: return self.back.get(i - self.front.size()) def set(self, i, x): if i < self.front.size(): return self.front.set(self.front.size() - i - 1, x) else: return self.back.set(i - self.front.size(), x) def add(self, i, x): if i < self.front.size(): self.front.add(self.front.size() - i, x) else: self.back.add(i - self.front.size(), x) self._balance() def remove(self, i): if i < self.front.size(): x = self.front.remove(self.front.size() - i - 1) else: x = self.back.remove(i - self.front.size()) self._balance() return x def _balance(self): n = self.size() mid = n // 2 if 3 * self.front.size() < self.back.size( ) or 3 * self.back.size() < self.front.size(): f = ArrayStack() for i in range(mid): f.add(i, self.get(mid - i - 1)) b = ArrayStack() for i in range(n - mid): b.add(i, self.get(mid + i)) self.front = f self.back = b def clear(self): self.front.clear() self.back.clear() def size(self): return self.front.size() + self.back.size()
class DualArrayDeque(BaseList): def __init__(self, iterable=[]): self._initialize() self.add_all(iterable) def _initialize(self): self.front = ArrayStack() self.back = ArrayStack() def get(self, i): if i < self.front.size(): return self.front.get(self.front.size() - i - 1) else: return self.back.get(i - self.front.size()) def set(self, i, x): if i < self.front.size(): return self.front.set(self.front.size() - i - 1, x) else: return self.back.set(i - self.front.size(), x) def add(self, i, x): if i < self.front.size(): self.front.add(self.front.size() - i, x) else: self.back.add(i - self.front.size(), x) self._balance() def remove(self, i): if i < self.front.size(): x = self.front.remove(self.front.size() - i - 1) else: x = self.back.remove(i - self.front.size()) self._balance() return x def _balance(self): n = self.size() mid = n // 2 if 3 * self.front.size() < self.back.size() or 3 * self.back.size() < self.front.size(): f = ArrayStack() for i in range(mid): f.add(i, self.get(mid - i - 1)) b = ArrayStack() for i in range(n - mid): b.add(i, self.get(mid + i)) self.front = f self.back = b def clear(self): self.front.clear() self.back.clear() def size(self): return self.front.size() + self.back.size()