#include<bits/stdc++.h>
using namespace std;
const int N = 1e6;
int a[N],n;
long long work(int x) {
long long l = 1,r = n,cnt = 0;
while(l < r) {
if(a[l] + a[r] <= x) {
cnt += r - l;
l ++;
}
else {
r --;
}
}
return cnt;
}
int main() {
int l,r;
cin>>n>>l>>r;
for(int i = 1; i <= n; i++) cin>>a[i];
sort(a+1,a+1+n);
cout<<work(r) - work(l-1);
}
- 它定义了一个全局数组
a
和一个整数n
。 work
是一个函数,接收整数x
作为参数并返回长整型数cnt
。- 在
main()
函数中,程序读取变量n
,l
和r
。 - 然后它循环地从输入读取
n
个整数到数组a
. - 对数组进行排序。
- 最后打印出两个工作函数的差值结果。
让我们分析一下这段程序更详细的行为:
- 数组长度为 n,并且需要处理区间
[l, r]
. - 使用快速输入输出处理大规模数据 (
#include<bits/stdc++.h>
是 C++ 编译器允许使用的所有标准库的集合)。 - 运用双指针技巧在排序后的数组中找到所有满足条件
(a[l] + a[r] <= x)
的配对数量。这里 x 先被设置为 r,也就是用户输入的上限;然后对 l 进行相同的处理但减去 1 并从计算结果中除掉(剔除不满足[l, r]
给定范围内配对数量)。
最终打印输出的值代表着有多少对 (i, j),其中 i < j,使得 a[i] + a[j] 处于给定区间 [l, r].
具体来说关于 work 函数:
- 变量 l (左指针)初始设置为 1,而 r (右指针)初始设置为 n。
- 循环直到左指针小于右指针停止。
- 如果当前两元素之和小于等于 x,则说明所有处于左指针和右指针之间(不包括右指针)与当前左指针所指向元素组合之和均小于等于 x;因此可以一次性添加 cnt 的数量,并且左指针向右移动。
- 如果两元素之和大于 x,则说明当前右指针所在位置太大了,需要将其向左移动以尝试找到较小元素的配对。
程序结束时打印输出 cnt 的累计总和。通过 work(r) - work(l - 1),我们实际上获取了在闭区间 [l, r] 内有效配对数量。