Untitled

mail@pastecode.io avatar
unknown
plain_text
8 days ago
1.8 kB
4
Indexable
Never
import bisect

M = 10**9 + 7

class Fancy:

    def __init__(self):
        self._base_transform = (1, 0)
        self._inverse_transform_indices = []
        self._inverse_transform_by_index = {}
        self._elements = []
        

    def append(self, val: int) -> None:
        self._elements.append(val)

    def addAll(self, inc: int) -> None:
        m, b = self._base_transform
        self._base_transform = (m, (b+inc) % M)
        curr_inverse = inverse(*self._base_transform)
        self._inverse_transform_indices.append(len(self._elements))
        self._inverse_transform_by_index[len(self._elements)] = curr_inverse

    def multAll(self, n: int) -> None:
        m, b = self._base_transform
        self._base_transform = ((m*n) % M, (b*n) % M)
        curr_inverse = inverse(*self._base_transform)
        self._inverse_transform_indices.append(len(self._elements))
        self._inverse_transform_by_index[len(self._elements)] = curr_inverse
        

    def getIndex(self, idx: int) -> int:
        if not 0 <= idx < len(self._elements):
            return -1
        index_point = bisect.bisect_right(self._inverse_transform_indices, idx) - 1
        if index_point != -1:
            inv_index = self._inverse_transform_indices[index_point]
            m_inv, b_inv = self._inverse_transform_by_index[inv_index]
        else:
            m_inv, b_inv = 1, 0
        base_val = self._elements[idx]
        inverse = (base_val * m_inv + b_inv) % M
        m, b = self._base_transform
        transformed = (m*inverse + b) % M
        return transformed

def inverse(m, b):
    return (pow(m, -1, M), (-b * pow(m, -1, M)) % M)


# Your Fancy object will be instantiated and called as such:
# obj = Fancy()
# obj.append(val)
# obj.addAll(inc)
# obj.multAll(m)
# param_4 = obj.getIndex(idx)
Leave a Comment