D. Ghost Ants
把向左走和向右走的蚂蚁分别存进两个数组并排序,对于两者都要枚举的情况,思路是只枚举一个,那枚举的这个就是一个固定值,问题就转化成如何快速找到另一个变量符合条件的值。
假设枚举向左走的蚂蚁,对第 i 个向左走的蚂蚁,在向右走的蚂蚁中求出坐标大于等于 a [ i ] - 2 * t 的蚂蚁数量。两次二分就可以,第一次用 lower 找到最左边的,第二次用 upper 找到最右边的下一个。
不管是 lower 还是 upper 都有可能返回 end ()
· lower 返回 end (),那 upper 也一定返回 end (),所以 r - l 为 0,不用特判
· upper 返回 end (),因为 end () 本身就是最后一个元素的下一个元素,指向的就是空节点,不会产生影响,所以也不用特判
因此不管返回的是不是 end (),都是直接 r - l
这里不用管 end () 是因为我只是在求符合条件的个数,而不是能不能查找到,是否存在。如果是要找具体的某一只蚂蚁那就得去特判是否返回的是 end ()
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 5, INF = 1e18;
int T, n, t, cnt, ans;
string s;
vector<int> v0, v1;
signed main()
{
cin >> n >> t >> s;
for (int i = 0; i < n; i ++)
{
int x;
cin >> x;
if (s[i] == '0') v0.push_back(x);
else v1.push_back(x);
}
sort(v0.begin(), v0.end());
sort(v1.begin(), v1.end());
int d = t * 2, cnt0 = v0.size(), cnt1 = v1.size();
for (int i = 0; i < cnt0; i ++)
{
auto l = lower_bound(v1.begin(), v1.end(), v0[i] - d);
auto r = upper_bound(v1.begin(), v1.end(), v0[i]);
ans += r - l;
}
cout << ans;
return 0;
}