✅Easy using Dictionary and SortedSet || 100% beats🔥
IntuitionThe task management system requires efficient handling of tasks based on their priority and task ID. The goal is to:
Retrieve and execute the highest-p
# Intuition
<!-- Describe your first thoughts on how to solve this problem. -->
The task management system requires efficient handling of tasks based on their priority and task ID. The goal is to:

1. Retrieve and execute the highest-priority task efficiently.
2. Allow dynamic operations such as adding, editing, and removing tasks with minimal overhead.

# Approach
<!-- Describe your approach to solving the problem. -->
To achieve this, we use two main data structures:

**1. Dictionary** (taskDict): This stores tasks using their taskId as the key. It enables constant-time access, modification, and deletion of tasks.

**2. SortedSet** (taskSet): This maintains all tasks in sorted order based on:
- Priority (descending): Tasks with higher priority are executed first.
- Task ID (descending): Among tasks with the same priority, the one with the highest taskId is executed first.

By combining these two structures:
- The dictionary ensures efficient updates to task details.
- The sorted set ensures efficient access to the task with the highest priority.


# Complexity
- **Time complexity:**
    **Initialization:** Adding M tasks during initialization involves inserting them into both data structures.
    Dictionary insertion: O(1) per task.
    SortedSet insertion: O(logN) per task.
    Total for initialization: O(M logM), where M represents the number of tasks

    **Add:**
    Dictionary insertion: O(1) per task.
    SortedSet insertion: O(logN) per task.
    Total for initialization: O(log N)

    **Edit:**
    Lookup in the dictionary: O(1).
    Removal from the sorted set: O(logN).
    Update in the dictionary: O(1).
    Insertion into the sorted set: O(logN).
    Total for Edit: O(logN).

    **Rmv:**
    Lookup in the dictionary: O(1).
    Removal from the sorted set: O(logN).
    Removal from the dictionary: O(1).
    Total for Rmv: O(logN).

    **ExecTop:**
    Retrieval of the top element from the sorted set: O(1) for access.
    Removal from the sorted set: O(logN).
    Removal from the dictionary: O(1).
    Total for ExecTop: O(logN).


- **Space complexity:** The system stores each task in both the dictionary and the sorted set:
    - Dictionary (taskDict): O(N), where N is the number of tasks.
    - SortedSet (taskSet): O(N), as each task is also stored in the sorted set.
    - Total Space Complexity: O(N).


# Code
```csharp []
public class TaskManager {
    // Dictionary to store tasks by taskId
    private Dictionary<int, (int userId, int priority)> taskDict;
    
    // sorted set to efficiently track tasks for execution
    private SortedSet<(int priority, int taskId, int userId)> taskSet;

    public TaskManager(IList<IList<int>> tasks) {
        taskDict = new Dictionary<int, (int userId, int priority)>();
        taskSet = new SortedSet<(int priority, int taskId, int userId)>(Comparer<(int priority, int taskId, int userId)>.Create((a, b) => {
            if(a.priority != b.priority) {
                return b.priority.CompareTo(a.priority); // Higher priority first
            }

            if (a.taskId != b.taskId)
                return b.taskId.CompareTo(a.taskId);     // Higher taskId first
            return a.userId.CompareTo(b.userId);         // Arbitrary tie-breaker
        }));

        foreach (var task in tasks) {
            int userId = task[0], taskId = task[1], priority = task[2];
            Add(userId, taskId, priority);
        }
    }
    
    public void Add(int userId, int taskId, int priority) {
        // Add task to dictionaries
        taskDict[taskId] = (userId, priority);
        taskSet.Add((priority, taskId, userId));
    }
    
    public void Edit(int taskId, int newPriority) {
        if (taskDict.TryGetValue(taskId, out var task))
        {
            // Remove old entry from taskSet
            taskSet.Remove((task.priority, taskId, task.userId));

            // Update taskDict
            taskDict[taskId] = (task.userId, newPriority);

            // Add updated entry to taskSet
            taskSet.Add((newPriority, taskId, task.userId));
        }
    }
    
    public void Rmv(int taskId) {
        if (taskDict.TryGetValue(taskId, out var task)) {
            // remove from both dictionaries
            taskSet.Remove((task.priority, taskId, task.userId));
            taskDict.Remove(taskId);
        }
    }
    
    public int ExecTop() {
        if (taskSet.Count == 0)
            return -1; // No tasks available

        // Get the highest-priority task
        var topTask = taskSet.First();

        // Remove it from the system
        taskSet.Remove(topTask);
        taskDict.Remove(topTask.taskId);

        // Return the userId associated with the task
        return topTask.userId;
    }
}

/**
 * Your TaskManager object will be instantiated and called as such:
 * TaskManager obj = new TaskManager(tasks);
 * obj.Add(userId,taskId,priority);
 * obj.Edit(taskId,newPriority);
 * obj.Rmv(taskId);
 * int param_4 = obj.ExecTop();
 */
```
['C#']