Acwing 1238. 日志统计(双指针)
https://www.acwing.com/problem/content/1240/
1238. 日志统计
输入样例:
7 10 2
0 1
0 10
10 10
10 1
9 1
100 3
100 3
输出样例:
1
3
首先注意数据范围,0-1e5的数据范围,两层循环的话肯定是会爆时的,这就需要优化到O(n)的时间之内
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=1e18,MINN=31;
const LL N=1e6+10,M=4010;
const double PI=3.1415926535;
#define endl '\n'
PII a[N];
bool st[N];
int main()
{
cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
int T=1;
//cin>>T;
while(T--)
{
LL n,d,k;
cin>>n>>d>>k;
for(int i=0;i<n;i++)
{
//在a[i].first这个时间点给a[i].second点了一个赞
cin>>a[i].first>>a[i].second;
}
sort(a,a+n);//按照时间顺序进行排序
/*for(int i=0;i<n;i++)
{
cout<<a[i].first<<" "<<a[i].second<<endl;
}*/
map<LL,LL> mp;
for(int i=0,j=0;i<n;i++)//按照已知点赞的时间顺序往后排列搜索
{
int id=a[i].second;//这个id
mp[id]++;//j时刻给id记录一下(为啥j从0开始?因为时间是从0开始的)
while(a[i].first-a[j].first>=d)//如果当前时间点到j这个时间点长度会大于d的话(时间拉的太长了)
{
mp[a[j].second]--;//减去我指针移动到的地方的id,管它有没有东西,我直接--,因为后续不再搜索这个id了
j++;//时间往右边收缩
}
if(mp[id]>=k) st[id]=true;//如果id数量达标,标记id位置
}
for(int i=0;i<1e5+10;i++)
{
if(st[i]) cout<<i<<endl;
}
}
return 0;
}