思路:
将信息按时间排序,然后类似于滑动窗口定义两个指针i,j计算时间跨度小于d的区域内的id次数,若是热帖则标记为答案,然后作指针i自增,抛出一个记录,相应id次数减一,循环上述步骤直至遍历完所有数据。所有数据只遍历一遍时间复杂度O(n),快排O(nlogn),故综合时间复杂度O(nlogn)。
C++ 代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#define ts first
#define id second
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 5;
int n, d, k;
vector<pii>q; //存时间和id
int cnt[N]; //存id出现次数
bool st[N]; //标记答案
int maxid; //存最大id
int main(){
scanf("%d%d%d", &n, &d, &k);
q.resize(n);
while(n --){
scanf("%d%d", &q[n].ts, &q[n].id);
maxid = max(maxid, q[n].id);
}
sort(q.begin(), q.end());
n = q.size();
int i = 0, j = 0;
while(j < n){ //类滑动窗口
while(j < n && q[j].ts < q[i].ts + d){
cnt[q[j].id] ++;
if(cnt[q[j].id] >= k) st[q[j].id] = 1;
j ++;
}
cnt[q[i].id] --;
i ++;
}
for(int i = 1; i <= maxid; i ++)
if(st[i]) cout << i << endl;
return 0;
}