Skip to content
Related Articles

Related Articles

Tree of Space – Locking and Unlocking N-Ary Tree

Improve Article
Save Article
  • Difficulty Level : Hard
  • Last Updated : 21 Nov, 2021
Improve Article
Save Article

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
Related Articles

Start Your Coding Journey Now!