A gate scanner logs the ID of every visitor. For every block of k consecutive entries, print how many different IDs appear in it.
Aim for O(n) expected time with std::unordered_map, not O(n·k).
Constraints
- 1 ≤ k ≤ n ≤ 10^5
- −10^9 ≤ each ID ≤ 10^9
Input and output
- Input
- First line: n and k. Second line: n integers.
- Output
- One line with n − k + 1 integers separated by spaces.
Examples
Input 1
7 3
1 2 1 3 4 2 3Output
2 3 3 3 3Windows: [1 2 1] has 2 distinct IDs, [2 1 3] 3, [1 3 4] 3, [3 4 2] 3, [4 2 3] 3.
Input 2
4 4
5 5 5 5Output
1One window with a single distinct ID.
Show hints
- Keep a count for each ID inside the current window.
- When the window slides, add the new ID and decrement the old one. Erase it when its count reaches 0, so that
size()equals the number of distinct IDs.
Show the explanation
Sliding window with a frequency map.
- Put the first k IDs into
unordered_map<int,int> cnt. The answer for the first window iscnt.size(). - For each new index i (from k to n−1):
++cnt[a[i]]adds the entering ID.if (--cnt[a[i-k]] == 0) cnt.erase(a[i-k]);removes the leaving ID.- Record
cnt.size().
Each step does a constant number of hash operations, so the total is O(n) expected time and O(k) memory. Rebuilding a set for every window costs O(n·k), which is too slow when n = 10^5 and k = 5·10^4.
C++ notes
cnt[x]inserts x with value 0 if it is missing. That is why the erase step is needed to keepsize()honest.unordered_maphas expected O(1) operations but O(n) in the worst case, for example with adversarial keys.std::mapguarantees O(log n). In contests people sometimes reserve buckets (cnt.reserve(2 * k)) or use a custom hash.
Original UniCircle question. Last reviewed 22 Oct 2026.
