[java] Easy to understand
IntuitionThe key is to handle the relationship between offline and @here event:
Two methods considered:
Maintain a TreeSet for each user to track their offline,
# Intuition
The key is to handle the relationship between offline and @here event:
Two methods considered:
1. Maintain a TreeSet for each user to track their offline, and for each @here event, find out who is impacted; O(logN * N * M)
2. Sort by timestamp. Be aware of the tie case whenever you do sorting!!! always put offline event before any message when timestamp ties.

# Approach
<!-- Describe your approach to solving the problem. -->

# Complexity
- Time complexity:
<!-- Add your time complexity here, e.g. $$O(n)$$ -->

- Space complexity:
<!-- Add your space complexity here, e.g. $$O(n)$$ -->

# Code
```java []
class Solution {
    // 1. TreeSet[] id -> OfflineSchedules
    // 2. sort by timestamp
    public int[] countMentions(int numberOfUsers, List<List<String>> events) {
        int[] res = new int[numberOfUsers];
        int allCount = 0, hereCount = 0;
        int[] offlineCounts = new int[numberOfUsers];
        Queue<List<String>> queue = new LinkedList<>(); // window

        Collections.sort(events, (e1, e2) -> {
            int t1 = Integer.valueOf(e1.get(1)), t2 = Integer.valueOf(e2.get(1));
            if (t1 != t2) return t1 - t2;
            return e2.get(0).compareTo(e1.get(0)); // OFFLINE will show first
        }); 

        for (List<String> event : events) {
            if (event.get(0).equals("OFFLINE")) queue.add(Arrays.asList(event.get(1), event.get(2))); // [time, userId]
            else {
                int time  = Integer.valueOf(event.get(1));
                switch (event.get(2)) {
                    case "ALL":
                        allCount++;
                        break;
                    case "HERE":
                        hereCount++;
                        while (!queue.isEmpty() && Integer.valueOf(queue.peek().get(0)) + 60 <= time) queue.poll(); // todo
                        for (List<String> user : queue) offlineCounts[Integer.valueOf(user.get(1))]++;
                        break;
                    default:
                        for (String user : event.get(2).split(" "))
                            res[Integer.valueOf(user.substring(2))]++;
                }
            }
        }

        for (int i = 0; i < res.length; i++)
            res[i] += allCount + hereCount - offlineCounts[i];

        return res;
    }
}
```
['Java']