easy Java solution using HashMap,  beat 100% time and space
IntuitionApproach
sort input events, process OFFLINE first
use HashMap<Integer, State> for each id
beat 100% time and 100% space
Complexity
Time complexity: O(n
# Intuition
<!-- Describe your first thoughts on how to solve this problem. -->

# Approach
- sort input events, process OFFLINE first 
- use HashMap<Integer, State> for each id
- beat 100% time and 100% space
<!-- Describe your approach to solving the problem. -->

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

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

# Code
```java []
class Solution {
    // case 1 dry run: id0: 
    private int[] res;
    private int n;
    private Map<Integer, State> cache;
    public int[] countMentions(int numberOfUsers, List<List<String>> events) {
        Collections.sort(events, 
                         (a, b) -> fn1(a) == fn1(b) ? fn2(a) - fn2(b) : fn1(a) - fn1(b));
        n = numberOfUsers;
        res = new int[n];
        cache = new HashMap<>();
        for (int id = 0; id < n; id++) {
            State one = new State(id, 0, true);
            cache.put(id, one);
        }
        for (List<String> event : events) {
            processEvent(event);
        }
        return res;
    }
    private int fn1(List<String> a) {
        String ts = a.get(1);
        return Integer.parseInt(ts);
    }
    private int fn2(List<String> a) {
        if (a.get(0).equals("OFFLINE")) {
            return 0;
        }
        return 1;
    }

    private void processEvent(List<String> event) {
        String msg = event.get(0);
        String tStr = event.get(1); int t = Integer.parseInt(tStr);
        String mention = event.get(2);
        if (msg.equals("MESSAGE")) {
            if (mention.equals("HERE")) {
                for (int id : cache.keySet()) {
                    State cur = cache.get(id);
                    if (cur.isOnline(t)) {
                        res[id]++;
                    }
                }
            } else if (mention.equals("ALL")) {
                for (int id : cache.keySet()) {
                    res[id]++;
                }
            } else {
                processMsg(t, mention);
            }
        } else if (msg.equals("OFFLINE")) {
            processOffline(t, mention);
        }
    }

    private void processOffline(int tm, String mention) {
        int id = Integer.parseInt(mention);
        if (cache.containsKey(id)) {
            State cur = cache.get(id);
            if (cur.timestamp >= tm) {
                res[cur.id]--;
            }
            cur.turnOffLine(tm);
        } 
    }

    private void processMsg(int tm, String msg) {
        String[] ids = msg.split(" ");
        for (String id : ids) {
            int i = 0;
            int num = 0;
            while (i < id.length()) {
                char c = id.charAt(i++);
                if (Character.isDigit(c)) {
                    num = num * 10 + (c - '0');
                }
            }
            res[num]++;
        }
    }

    private static class State {
        int id;
        int timestamp;
        boolean online;
        
        State(int i, int t, boolean on) {
            id = i;
            timestamp = t;
            online = on;
        }

        public boolean isOnline(int now) {
            if (this.online) {
                return true;
            }
            if (now - this.timestamp >= 60) {
                this.online = true;
                timestamp = now;
            }
            return this.online;
        }

        public void turnOffLine(int now) {
            this.online = false;
            this.timestamp = now;
        }
    }
}
```
['Java']