ABC 360

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值