C++ max heap, map solution
IntuitionUse max heap for storing the tasks (order on the basis of priority) and maps for storing the information of a given task. We also use a "present" map t
# Intuition
Use max heap for storing the tasks (order on the basis of priority) and maps for storing the information of a given task. We also use a "present" map to keep track of whether a task is present or not. Read the approach.

# Approach
We keep tasks in a priority queue. mp stores the task - {priority, userId}. present stores whether a task is present.
For Add - we simply add the new task to pq. store the priority and user id of the new task in mp. marks present for the task as true.
For edit - we add the new {pq,taskId} in the pq. And we change the mp[taskId] by updating the new priority. (Note - the same task with the 
old priority is still present, but the priority of the task in mp has been updated. So if we encounter this task in pq at a later stage, 
we can simply compare the priority with that of the mp and remove it.)
For remove - We simply mark present for task id as false.
For execTop() - For the top we check if the task is present or not, if not we remove it.
If present we check if the priority of the task matches with that of the present in mp. If not, that means we must have edited this task 
before and this instance of the task is dummy so we remove it. Inside a while loop we keep doing it until we get an element that doesn't 
fall under this condition and can be removed.
If pq gets empty befoe that we return -1 as that means there is no task currently.
Or else from the mp map, we check the user id of the task and return it. We also remove this element from the pq.

# Complexity
- Time complexity:
add - O(log n)
edit - O(log n)
remove - O(1)
execTop() - O(n log n)

# Code
```cpp []
class TaskManager {
public:
    priority_queue<pair<int,int>> pq;  // priority,taskId
    unordered_map<int,pair<int,int>> mp;  // taskId -> priority, userId
    unordered_map<int,bool> present;   // taskId -> present or not


    TaskManager(vector<vector<int>>& tasks) {
        for(int i=0; i<tasks.size(); i++){
            this->pq.push({tasks[i][2], tasks[i][1]});
            this->mp[tasks[i][1]]={tasks[i][2],tasks[i][0]};
            this->present[tasks[i][1]]=true;
        }
    }
    
    void add(int userId, int taskId, int priority) {
        this->pq.push({priority,taskId});
        this->mp[taskId]={priority,userId};
        this->present[taskId] = true;
    }
    
    void edit(int taskId, int newPriority) {
        this->pq.push({newPriority,taskId});
        this->mp[taskId] = {newPriority,mp[taskId].second};
    }
    
    void rmv(int taskId) {
        this->present[taskId] = false;
    }
    
    int execTop() {
        while((!this->pq.empty()) && (!this->present[this->pq.top().second] || this->pq.top().first != this->mp[this->pq.top().second].first)){
            this->pq.pop();
        }
        if(pq.empty()) return -1;
        auto it = this->pq.top();
        this->pq.pop();
        this->present[it.second] = false;
        return this->mp[it.second].second;
    }
};

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