
前言
二分查找不仅是基础数据结构,更是解决计数与最优化问题的利器。本文将通过 A-B 数对统计与高考志愿匹配两道经典例题,拆解排序预处理、STL 函数应用及手动实现时的边界细节。
一、A-B 数对
1.1 题目描述
给定 n 个数和一个整数 c,求有多少对 (i, j) 满足 a[i] - a[j] = c。
1.2 核心思路
既然顺序不影响结果,不妨先对数组排序,观察数据分布规律。由等式 A - B = C 可推导出 B = A - C。C 是已知常数,我们只需枚举每一个 A,在已排序的序列中快速查找对应的 B 的数量。
这里可以利用 STL 提供的二分接口:
lower_bound:返回第一个大于等于 k 的位置(左闭右开区间)。upper_bound:返回第一个大于 k 的位置。
两个指针相减,即为区间内等于 k 的元素个数。
示例:数组为 [10, 20, 20, 20, 30, 40],查询 20。 lower_bound 返回索引 2,upper_bound 返回索引 5。 区间长度 = 5 - 2 = 3,即有三个 20。

1.3 代码实现
注意,STL 二分函数仅适用于有序序列。若数组无序,需先排序;但通用二分逻辑只要满足「二段性」即可适用。
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
LL a[N];
int main() {
int n, c;
cin >> n >> c;
for (int i = 1; i <= n; i++) cin >> a[i];
// 排序是二分的前提
(a + , a + + n);
LL ret = ;
( i = ; i <= n; i++) {
LL b = a[i] - c;
ret += (a + , a + i + , b) - (a + , a + + i, b);
}
cout << ret << endl;
;
}


