Versioning approach
IntuitionAdd version to the task this will tell us if the task exisits and if it is not stale.ApproachStore tasks in map to quickly access by taskId.
Also store
# Intuition
<!-- Describe your first thoughts on how to solve this problem. -->
Add version to the task this will tell us if the task exisits and if it is not stale.
# Approach
<!-- Describe your approach to solving the problem. -->
Store tasks in map to quickly access by taskId.
Also store all of the versions in heap to quickly acccess potential task to execute.
Everytime we pop stale of non existing task skip it.

# Complexity
- Time complexity:
<!-- Add your time complexity here, e.g. $$O(n)$$ -->
O(nlogn) - I guess we will have to pop everything from the heap in the worst case.
- Space complexity:
<!-- Add your space complexity here, e.g. $$O(n)$$ -->
O(n)
# Code
```cpp []
class TaskManager {
private:
    struct Task {
        int userId, taskId, priority, version;
        Task() {}
        Task(int u, int t, int p, int v = 0): userId(u), taskId(t), priority(p), version(v) {}
    };
    static constexpr auto cmp = [](const Task& l, const Task& r) {

            if (l.priority == r.priority)
                return l.taskId < r.taskId;
            return l.priority < r.priority;

    };
    map<int, Task> tasksMap;
    priority_queue<Task, vector<Task>, decltype(cmp)> taskByPrior;
public:
    TaskManager(vector<vector<int>>& taskss) {
        for (auto & t: taskss)
        {
            tasksMap[t[1]] = Task(t[0], t[1], t[2]);
            taskByPrior.push(Task(t[0], t[1], t[2]));
        }
    }
    
    void add(int userId, int taskId, int priority) {
        int oldVersion = -1;
        if (tasksMap.count(taskId))
            oldVersion = tasksMap[taskId].version;
        tasksMap[taskId] = Task(userId, taskId, priority, oldVersion + 1);
        taskByPrior.push(tasksMap[taskId]);        
    }
    
    void edit(int taskId, int newPriority) {
        int old = tasksMap[taskId].priority;
        tasksMap[taskId].priority = newPriority;
        tasksMap[taskId].version++;
        taskByPrior.push(tasksMap[taskId]);
    }
    
    void rmv(int taskId) {
        tasksMap[taskId].version++;
    }
    
    int execTop() {
        while (!taskByPrior.empty())
        {
            
            auto t = taskByPrior.top(); taskByPrior.pop();
            if (!tasksMap.count(t.taskId) || t.version != tasksMap[t.taskId].version)
                continue;
            else
                return t.userId;
        }
        return -1;
    }
};

/**
 * 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++']