C++ Ezee Pzee Solution. Beats (100%) 
IntuitionFor getting taskId with at most priority we can use heap structure. But priority_queue in C++ supports removal of top element not any element in log(n)
# Intuition
For getting taskId with at most priority we can use heap structure. But priority_queue in C++ supports removal of top element not any element in log(n) time. So we can use multiset/set which supports finding any element in log(n) time and deletion in log(n) time.

# Approach
Created a customComparator for ordering of elements in multiset with highest priority and highest taskId in case of matching priority.

Created an unordered_map for finding the user assigned to a given task.
Created an unordered_map for finding the priority assigned to a given task. Its helpful in editing priority of a given task. We can use taskId and priority combination to find the element in the set and remove it and again add a new one.

**Note**
```We can use set also as combination of taskId and priority will always   be unique as taskId is unique.```

# Complexity
- Time complexity:
O(nlogn)

- Space complexity:
O(n) 

# Code
```cpp []
class Task{
public:    
    int taskId;
    int priority;
    
    Task(int taskId, int priority) : priority(priority), taskId(taskId) {};
};

struct CustomComparator {
    bool operator() (const Task& a, const Task& b) const{
        if(a.priority == b.priority)
             return a.taskId > b.taskId;
        return a.priority > b.priority;
    }
};

class TaskManager {   
public:
    multiset<Task, CustomComparator> taskSet;
    unordered_map<int,int> taskToUserMap;
    unordered_map<int,int> taskToPriorityMap;
    
    TaskManager(vector<vector<int>>& tasks) {
       // O(nlogn) if n tasks are there.
        for(auto &task: tasks) {
            taskSet.insert(Task(task[1],task[2])); //O(logn)
            taskToUserMap[task[1]] = task[0]; //O(1)
            taskToPriorityMap[task[1]] = task[2]; //O(1)
        }
    }
    
    void add(int userId, int taskId, int priority) {
        taskSet.insert(Task(taskId,priority)); // O(logn)
        taskToUserMap[taskId] = userId; //O(1)
        taskToPriorityMap[taskId] = priority; //O(1)
    }
    
    void edit(int taskId, int newPriority) {
        int oldPriority = taskToPriorityMap[taskId]; // O(1)
        taskToPriorityMap[taskId] = newPriority; //O(1)
        auto it = taskSet.find(Task(taskId, oldPriority)); //O(logn)
        taskSet.erase(it); //O(1)
        taskSet.insert(Task(taskId, newPriority)); O(logn)
    }
    
    void rmv(int taskId) {
        int priority = taskToPriorityMap[taskId]; // O(1)
        taskToPriorityMap.erase(taskToPriorityMap.find(taskId)); //O(logn)
        taskToUserMap.erase(taskToUserMap.find(taskId)); //O(logn)
        taskSet.erase(taskSet.find(Task(taskId,priority))); // O(logn)
    }
    
    int execTop() {
        if(taskSet.size() == 0)
            return -1;
        Task task = *taskSet.begin(); //O(1)
        int userId = taskToUserMap[task.taskId]; //O(1)
        rmv(task.taskId); //O(logn)
        return 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();
 */
```
['Heap (Priority Queue)', 'Ordered Set', 'C++']