# Tree of Space – Locking and Unlocking N-Ary Tree

• Difficulty Level : Hard
• Last Updated : 21 Nov, 2021

Given a world map in the form of Generic M-ary Tree consisting of N nodes and an array queries[], the task is to implement the functions Lock, Unlock and Upgrade for the given tree. For each query in queries[], the functions return true when the operation is performed successfully, otherwise it returns false. The functions are defined as:

X: Name of the node in the tree and will be unique
uid: User Id for the person who accesses node X

1. Lock(X, uid): Lock takes exclusive access to the subtree rooted.

• Once Lock(X, uid) succeeds, then lock(A, any user) should fail, where A is a descendant of X.
• Lock(B. any user) should fail where X is a descendant of B.
• Lock operation cannot be performed on a node that is already locked.

2. Unlock(X, uid): To unlock the locked node.

• The unlock reverts what was done by the Lock operation.
• It can only be called on same and unlocked by same uid.

3. UpgradeLock(X, uid): The user uid can upgrade their lock to an ancestor node.

• It is only possible if any ancestor node is only locked by the same user uid.
• The Upgrade should fail if there is any node that is locked by some other uid Y below.

Examples:

Input: N = 7, M = 2, nodes = [‘World’, ‘Asia’, ‘Africa’, ‘China’, ‘India’, ‘SouthAfrica’, ‘Egypt’],
queries =  [‘1 China 9’, ‘1 India 9’, ‘3 Asia 9’, ‘2 India 9’, ‘2 Asia 9’]
Output: true true true false true

Input: N = 3, M = 2, nodes = [‘World’, ‘China’, ‘India’],
queries =  [‘3 India 1’, ‘1 World 9’]
Output: false true

Below is the implementation of the above approach:

## Python3

 `# Python Implementation` `# Locking function``def` `lock(name):``    ``ind ``=` `nodes.index(name)``+``1``    ``c1 ``=` `ind ``*` `2``    ``c2 ``=` `ind ``*` `2` `+` `1``    ``if` `status[name] ``=``=` `'lock'` `\``            ``or` `status[name] ``=``=` `'fail'``:``        ``return` `'false'``    ``else``:``        ``p ``=` `ind``/``/``2``        ``status[nodes[p``-``1``]] ``=` `'fail'``        ``status[name] ``=` `'lock'``        ``return` `'true'` `# Unlocking function``def` `unlock(name):``    ``if` `status[name] ``=``=` `'lock'``:``        ``status[name] ``=` `'unlock'``        ``return` `'true'``    ``else``:``        ``return` `'false'` `# Upgrade function``def` `upgrade(name):``    ``ind ``=` `nodes.index(name)``+``1` `    ``# left child of ind``    ``c1 ``=` `ind ``*` `2` `    ``# right child of ind``    ``c2 ``=` `ind ``*` `2` `+` `1``    ``if` `c1 ``in` `range``(``1``, n) ``and` `c2 ``in` `range``(``1``, n):``        ``if` `status[nodes[c1``-``1``]] ``=``=` `'lock'` `\``            ``and` `status[nodes[c2``-``1``]] ``=``=` `'lock'``:``            ``status[nodes[c1``-``1``]] ``=` `'unlock'``            ``status[nodes[c2``-``1``]] ``=` `'unlock'``            ``status[nodes[ind``-``1``]] ``=` `'lock'``            ``return` `'true'``        ``else``:``            ``return` `'false'` `# Precomputation``def` `precompute(queries):``  ``d ``=` `[]``  ` `  ``# Traversing the queries``  ``for` `j ``in` `queries:``      ``i ``=` `j.split()``      ``d.append(i[``1``])``      ``d.append(``int``(i[``0``]))` `  ``status ``=` `{}``  ``for` `j ``in` `range``(``0``, ``len``(d)``-``1``, ``2``):``      ``status[d[j]] ``=` `0``  ``return` `status, d` `# Function to perform operations``def` `operation(name, code):``    ``result ``=` `'false'``    ` `    ``# Choose operation to perform``    ``if` `code ``=``=` `1``:``        ``result ``=` `lock(name)``    ``elif` `code ``=``=` `2``:``        ``result ``=` `unlock(name)``    ``elif` `code ``=``=` `3``:``        ``result ``=` `upgrade(name)``    ``return` `result``  ` `  ` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``  ` `      ``# Given Input``    ``n ``=` `7``;m ``=` `2``    ``apis ``=` `5``    ``nodes ``=` `[``'World'``, ``'Asia'``, \``            ``'Africa'``, ``'China'``, \``            ``'India'``, ``'SouthAfrica'``, ``'Egypt'``]``    ``queries ``=` `[``'1 China 9'``, ``'1 India 9'``, \``             ``'3 Asia 9'``, ``'2 India 9'``, ``'2 Asia 9'``]``    ` `    ``# Precomputation``    ``status, d ``=` `precompute(queries)` `    ``# Function Call``    ``for` `j ``in` `range``(``0``, ``len``(d) ``-` `1``, ``2``):``        ``print``(operation(d[j], d[j ``+` `1``]), end ``=` `' '``)`

Output:

`true true true false true`

Time Complexity: O(LogN)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up