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;
}
posted @ 2023-02-27 19:03  Vijurria  阅读(16)  评论(0编辑  收藏  举报