class FTree:
def __init__(self, f):
self.n = len(f)
self.ft = [0] * (self.n + 1)
for i in range(1, self.n + 1):
self.ft[i] += f[i - 1]
if i + self.lsone(i) <= self.n:
self.ft[i + self.lsone(i)] += self.ft[i]
def lsone(self, s):
return s & (-s)
def query(self, i, j):
if i > 1:
return self.query(1, j) - self.query(1, i - 1)
s = 0
while j > 0:
s += self.ft[j]
j -= self.lsone(j)
return s
def update(self, i, v):
while i <= self.n:
self.ft[i] += v
i += self.lsone(i)
def select(self, k):
p = 1
while (p * 2) <= self.n: p *= 2
i = 0
while p > 0:
if i + p < len(self.ft) and k > self.ft[i + p]:
k -= self.ft[i + p]
i += p
p //= 2
return i + 1
def main():
for size in range(1,1000+1):
ft = FTree([1]*size)
for i in range(1,size+1):
if ft.select(i)!=i:
print(f'Failed at size {size} at index {i}')
exit(1)
main()
Y2xhc3MgRlRyZWU6CiAgICBkZWYgX19pbml0X18oc2VsZiwgZik6CiAgICAgICAgc2VsZi5uID0gbGVuKGYpCiAgICAgICAgc2VsZi5mdCA9IFswXSAqIChzZWxmLm4gKyAxKQoKICAgICAgICBmb3IgaSBpbiByYW5nZSgxLCBzZWxmLm4gKyAxKToKICAgICAgICAgICAgc2VsZi5mdFtpXSArPSBmW2kgLSAxXQogICAgICAgICAgICBpZiBpICsgc2VsZi5sc29uZShpKSA8PSBzZWxmLm46CiAgICAgICAgICAgICAgICBzZWxmLmZ0W2kgKyBzZWxmLmxzb25lKGkpXSArPSBzZWxmLmZ0W2ldCgogICAgZGVmIGxzb25lKHNlbGYsIHMpOgogICAgICAgIHJldHVybiBzICYgKC1zKQoKICAgIGRlZiBxdWVyeShzZWxmLCBpLCBqKToKICAgICAgICBpZiBpID4gMToKICAgICAgICAgICAgcmV0dXJuIHNlbGYucXVlcnkoMSwgaikgLSBzZWxmLnF1ZXJ5KDEsIGkgLSAxKQoKICAgICAgICBzID0gMAogICAgICAgIHdoaWxlIGogPiAwOgogICAgICAgICAgICBzICs9IHNlbGYuZnRbal0KICAgICAgICAgICAgaiAtPSBzZWxmLmxzb25lKGopCgogICAgICAgIHJldHVybiBzCgogICAgZGVmIHVwZGF0ZShzZWxmLCBpLCB2KToKICAgICAgICB3aGlsZSBpIDw9IHNlbGYubjoKICAgICAgICAgICAgc2VsZi5mdFtpXSArPSB2CiAgICAgICAgICAgIGkgKz0gc2VsZi5sc29uZShpKQoKICAgIGRlZiBzZWxlY3Qoc2VsZiwgayk6CiAgICAgICAgcCA9IDEKICAgICAgICB3aGlsZSAocCAqIDIpIDw9IHNlbGYubjogcCAqPSAyCgogICAgICAgIGkgPSAwCiAgICAgICAgd2hpbGUgcCA+IDA6CiAgICAgICAgICAgIGlmIGkgKyBwIDwgbGVuKHNlbGYuZnQpIGFuZCBrID4gc2VsZi5mdFtpICsgcF06CiAgICAgICAgICAgICAgICBrIC09IHNlbGYuZnRbaSArIHBdCiAgICAgICAgICAgICAgICBpICs9IHAKICAgICAgICAgICAgcCAvLz0gMgoKICAgICAgICByZXR1cm4gaSArIDEKCmRlZiBtYWluKCk6Cglmb3Igc2l6ZSBpbiByYW5nZSgxLDEwMDArMSk6CgkJZnQgPSBGVHJlZShbMV0qc2l6ZSkKCQlmb3IgaSBpbiByYW5nZSgxLHNpemUrMSk6CgkJCWlmIGZ0LnNlbGVjdChpKSE9aToKCQkJCXByaW50KGYnRmFpbGVkIGF0IHNpemUge3NpemV9IGF0IGluZGV4IHtpfScpCgkJCQlleGl0KDEpCgptYWluKCkKCg==