s = "A(BB(CC))"
# 012345678
def build_tree(s, root = {"children": [], "l": 0}, i = 0, j = 0):
if i == len(s):
return (root, i)
cs = root["children"]
if s[i] == ")":
if cs and isinstance(cs[-1], list):
cs[-1][1] = i - 1
cs[-1][3] = j - 1
root["r"] = root["l"] + 2 * (j - root["l"]) - 1
return (root, i + 1)
if s[i] == "(":
if cs and isinstance(cs[-1], list):
cs[-1][1] = i - 1
cs[-1][3] = j - 1
child, next_i, = build_tree(s, {"children": [], "l": j}, i+1, j)
root["r"] = child["r"]
root["children"].append(child)
return build_tree(s, root, next_i, root["r"] + 1)
if not cs or not isinstance(cs[-1], list):
root["children"].append([i, None, j, None])
root["r"] = j
return build_tree(s, root, i + 1, j + 1)
def query(s, root, l, r):
out = ""
for child in root["children"]:
if isinstance(child, list):
# leaf starts at or after l
if l <= child[2] <= r:
out += s[child[0]:child[1] + 1 - max(0, child[3] - r)]
# leaf starts before l
elif child[2] < l <= child[3]:
out += s[child[0] + l - child[2]:child[1] + 1]
# parenthetical starts after r
elif child["l"] > r:
return out
# parenthetical ends before l
elif child["r"] < l:
continue
else:
stored_r = child["l"] + (child["r"] - child["l"]) // 2
print((l, stored_r, child))
out += query(s, child, l, min(stored_r, r))
if r >= stored_r:
out += query(s, child, max(l, child["l"]), stored_r)
return out
import json
root, i = build_tree(s)
print(query(s, root, 3, 8))
print(json.dumps(root, indent=2))
cyA9ICJBKEJCKENDKSkiCiMgICAgICAwMTIzNDU2NzgKCgpkZWYgYnVpbGRfdHJlZShzLCByb290ID0geyJjaGlsZHJlbiI6IFtdLCAibCI6IDB9LCBpID0gMCwgaiA9IDApOgogIGlmIGkgPT0gbGVuKHMpOgogICAgcmV0dXJuIChyb290LCBpKQoKICBjcyA9IHJvb3RbImNoaWxkcmVuIl0KCiAgaWYgc1tpXSA9PSAiKSI6CiAgICBpZiBjcyBhbmQgaXNpbnN0YW5jZShjc1stMV0sIGxpc3QpOgogICAgICBjc1stMV1bMV0gPSBpIC0gMQogICAgICBjc1stMV1bM10gPSBqIC0gMQogICAgcm9vdFsiciJdID0gcm9vdFsibCJdICsgMiAqIChqIC0gcm9vdFsibCJdKSAtIDEKICAgIHJldHVybiAocm9vdCwgaSArIDEpCgogIGlmIHNbaV0gPT0gIigiOgogICAgaWYgY3MgYW5kIGlzaW5zdGFuY2UoY3NbLTFdLCBsaXN0KToKICAgICAgY3NbLTFdWzFdID0gaSAtIDEKICAgICAgY3NbLTFdWzNdID0gaiAtIDEKICAgIGNoaWxkLCBuZXh0X2ksID0gYnVpbGRfdHJlZShzLCB7ImNoaWxkcmVuIjogW10sICJsIjogan0sIGkrMSwgaikKICAgIHJvb3RbInIiXSA9IGNoaWxkWyJyIl0KICAgIHJvb3RbImNoaWxkcmVuIl0uYXBwZW5kKGNoaWxkKQogICAgcmV0dXJuIGJ1aWxkX3RyZWUocywgcm9vdCwgbmV4dF9pLCByb290WyJyIl0gKyAxKQoKICBpZiBub3QgY3Mgb3Igbm90IGlzaW5zdGFuY2UoY3NbLTFdLCBsaXN0KToKICAgIHJvb3RbImNoaWxkcmVuIl0uYXBwZW5kKFtpLCBOb25lLCBqLCBOb25lXSkKCiAgcm9vdFsiciJdID0gagogIHJldHVybiBidWlsZF90cmVlKHMsIHJvb3QsIGkgKyAxLCBqICsgMSkKCgpkZWYgcXVlcnkocywgcm9vdCwgbCwgcik6CiAgb3V0ID0gIiIKICBmb3IgY2hpbGQgaW4gcm9vdFsiY2hpbGRyZW4iXToKICAgIGlmIGlzaW5zdGFuY2UoY2hpbGQsIGxpc3QpOgogICAgICAjIGxlYWYgc3RhcnRzIGF0IG9yIGFmdGVyIGwKICAgICAgaWYgbCA8PSBjaGlsZFsyXSA8PSByOgogICAgICAgIG91dCArPSBzW2NoaWxkWzBdOmNoaWxkWzFdICsgMSAtIG1heCgwLCBjaGlsZFszXSAtIHIpXQogICAgICAjIGxlYWYgc3RhcnRzIGJlZm9yZSBsCiAgICAgIGVsaWYgY2hpbGRbMl0gPCBsIDw9IGNoaWxkWzNdOgogICAgICAgIG91dCArPSBzW2NoaWxkWzBdICsgbCAtIGNoaWxkWzJdOmNoaWxkWzFdICsgMV0KICAgICMgcGFyZW50aGV0aWNhbCBzdGFydHMgYWZ0ZXIgcgogICAgZWxpZiBjaGlsZFsibCJdID4gcjoKICAgICAgcmV0dXJuIG91dAogICAgIyBwYXJlbnRoZXRpY2FsIGVuZHMgYmVmb3JlIGwKICAgIGVsaWYgY2hpbGRbInIiXSA8IGw6CiAgICAgIGNvbnRpbnVlCiAgICBlbHNlOgogICAgICBzdG9yZWRfciA9IGNoaWxkWyJsIl0gKyAoY2hpbGRbInIiXSAtIGNoaWxkWyJsIl0pIC8vIDIKICAgICAgcHJpbnQoKGwsIHN0b3JlZF9yLCBjaGlsZCkpCiAgICAgIG91dCArPSBxdWVyeShzLCBjaGlsZCwgbCwgbWluKHN0b3JlZF9yLCByKSkKICAgICAgaWYgciA+PSBzdG9yZWRfcjoKICAgICAgICBvdXQgKz0gcXVlcnkocywgY2hpbGQsIG1heChsLCBjaGlsZFsibCJdKSwgc3RvcmVkX3IpCiAgcmV0dXJuIG91dAoKaW1wb3J0IGpzb24KCnJvb3QsIGkgPSBidWlsZF90cmVlKHMpCgpwcmludChxdWVyeShzLCByb290LCAzLCA4KSkKCnByaW50KGpzb24uZHVtcHMocm9vdCwgaW5kZW50PTIpKQ==
(3, 6, {'children': [[2, 3, 1, 2], {'children': [[5, 6, 3, 4]], 'l': 3, 'r': 6}], 'l': 1, 'r': 12})
(3, 4, {'children': [[5, 6, 3, 4]], 'l': 3, 'r': 6})
(3, 4, {'children': [[5, 6, 3, 4]], 'l': 3, 'r': 6})
CCCCCCCC
{
"children": [
[
0,
0,
0,
0
],
{
"children": [
[
2,
3,
1,
2
],
{
"children": [
[
5,
6,
3,
4
]
],
"l": 3,
"r": 6
}
],
"l": 1,
"r": 12
}
],
"l": 0,
"r": 12
}