思路
当一头奶牛左边D距离内而且右边D距离内有身高至少是它的两倍的奶牛
不难想到使用单调队列(机房大佬Canstant0x5F3759DF使用的线段树我是不会)
从左到右、从右到左各扫一遍即可。
代码
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#define int long long
using namespace std;
const int MAXN = 5e4 + 5;
int n, d, cnt;
bool ans1[MAXN], ans2[MAXN];
deque<int> q;
struct cow
{
int x, h;
bool operator <(const cow &p)const
{
return x < p.x;
}
}a[MAXN];
signed main()
{
scanf("%lld%lld", &n, &d);
for (int i = 1; i <= n; i++)
{
scanf("%lld%lld", &a[i].x, &a[i].h);
}
sort(a + 1, a + n + 1);
for (int i = 1; i <= n; i++)
{
while (!q.empty() && a[q.back()].h < a[i].h)
{
q.pop_back();
}
while (!q.empty() && a[i].x - a[q.front()].x > d)
{
q.pop_front();
}
q.push_back(i);
if (a[q.front()].h >= (a[i].h << 1)) //等价于a[i].h * 2
{
ans1[i] = true;
}
}
q.clear();
for (int i = n; i; i--)
{
while (!q.empty() && a[q.back()].h < a[i].h)
{
q.pop_back();
}
while (!q.empty() && a[q.front()].x - a[i].x > d)
{
q.pop_front();
}
q.push_back(i);
if (a[q.front()].h >= (a[i].h << 1))
{
ans2[i] = true;
}
}
for (int i = 1; i <= n; i++)
{
if (ans1[i] && ans2[i]) //如果两个同时满足
{
cnt++;
}
}
printf("%lld", cnt);
return 0;
}