def getStaleSkillCount(numSkills, requestLogs, queryTimes, timeWindow):
from collections import defaultdict
# Sort request logs by timestamp
requestLogs.sort(key=lambda x: x[1])
# Attach index to each query for placing results in correct order
indexed_queries = sorted([(qt, i) for i, qt in enumerate(queryTimes)])
result = [0] * len(queryTimes)
m = len(requestLogs)
left = 0
right = 0
# Use a dict to track counts of skillIDs seen in the current window
active_skills = defaultdict(int)
for qt, idx in indexed_queries:
start_time = qt - timeWindow
# Expand the right side of the window
while right < m and requestLogs[right][1] <= qt:
skill_id, ts = requestLogs[right]
if ts >= start_time:
active_skills[skill_id] += 1
right += 1
# Shrink the left side of the window
while left < m and requestLogs[left][1] < start_time:
skill_id, ts = requestLogs[left]
if active_skills[skill_id] > 0:
active_skills[skill_id] -= 1
if active_skills[skill_id] == 0:
del active_skills[skill_id]
left += 1
result[idx] = numSkills - len(active_skills)
return result
ZGVmIGdldFN0YWxlU2tpbGxDb3VudChudW1Ta2lsbHMsIHJlcXVlc3RMb2dzLCBxdWVyeVRpbWVzLCB0aW1lV2luZG93KToKICAgIGZyb20gY29sbGVjdGlvbnMgaW1wb3J0IGRlZmF1bHRkaWN0CgogICAgIyBTb3J0IHJlcXVlc3QgbG9ncyBieSB0aW1lc3RhbXAKICAgIHJlcXVlc3RMb2dzLnNvcnQoa2V5PWxhbWJkYSB4OiB4WzFdKQoKICAgICMgQXR0YWNoIGluZGV4IHRvIGVhY2ggcXVlcnkgZm9yIHBsYWNpbmcgcmVzdWx0cyBpbiBjb3JyZWN0IG9yZGVyCiAgICBpbmRleGVkX3F1ZXJpZXMgPSBzb3J0ZWQoWyhxdCwgaSkgZm9yIGksIHF0IGluIGVudW1lcmF0ZShxdWVyeVRpbWVzKV0pCiAgICByZXN1bHQgPSBbMF0gKiBsZW4ocXVlcnlUaW1lcykKCiAgICBtID0gbGVuKHJlcXVlc3RMb2dzKQogICAgbGVmdCA9IDAKICAgIHJpZ2h0ID0gMAoKICAgICMgVXNlIGEgZGljdCB0byB0cmFjayBjb3VudHMgb2Ygc2tpbGxJRHMgc2VlbiBpbiB0aGUgY3VycmVudCB3aW5kb3cKICAgIGFjdGl2ZV9za2lsbHMgPSBkZWZhdWx0ZGljdChpbnQpCgogICAgZm9yIHF0LCBpZHggaW4gaW5kZXhlZF9xdWVyaWVzOgogICAgICAgIHN0YXJ0X3RpbWUgPSBxdCAtIHRpbWVXaW5kb3cKCiAgICAgICAgIyBFeHBhbmQgdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIHdpbmRvdwogICAgICAgIHdoaWxlIHJpZ2h0IDwgbSBhbmQgcmVxdWVzdExvZ3NbcmlnaHRdWzFdIDw9IHF0OgogICAgICAgICAgICBza2lsbF9pZCwgdHMgPSByZXF1ZXN0TG9nc1tyaWdodF0KICAgICAgICAgICAgaWYgdHMgPj0gc3RhcnRfdGltZToKICAgICAgICAgICAgICAgIGFjdGl2ZV9za2lsbHNbc2tpbGxfaWRdICs9IDEKICAgICAgICAgICAgcmlnaHQgKz0gMQoKICAgICAgICAjIFNocmluayB0aGUgbGVmdCBzaWRlIG9mIHRoZSB3aW5kb3cKICAgICAgICB3aGlsZSBsZWZ0IDwgbSBhbmQgcmVxdWVzdExvZ3NbbGVmdF1bMV0gPCBzdGFydF90aW1lOgogICAgICAgICAgICBza2lsbF9pZCwgdHMgPSByZXF1ZXN0TG9nc1tsZWZ0XQogICAgICAgICAgICBpZiBhY3RpdmVfc2tpbGxzW3NraWxsX2lkXSA+IDA6CiAgICAgICAgICAgICAgICBhY3RpdmVfc2tpbGxzW3NraWxsX2lkXSAtPSAxCiAgICAgICAgICAgICAgICBpZiBhY3RpdmVfc2tpbGxzW3NraWxsX2lkXSA9PSAwOgogICAgICAgICAgICAgICAgICAgIGRlbCBhY3RpdmVfc2tpbGxzW3NraWxsX2lkXQogICAgICAgICAgICBsZWZ0ICs9IDEKCiAgICAgICAgcmVzdWx0W2lkeF0gPSBudW1Ta2lsbHMgLSBsZW4oYWN0aXZlX3NraWxscykKCiAgICByZXR1cm4gcmVzdWx0Cg==