3月6日 双指针聪明的小羊肖恩

#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);
}
  1. 它定义了一个全局数组 a 和一个整数 n
  2. work 是一个函数,接收整数 x 作为参数并返回长整型数 cnt
  3. 在 main() 函数中,程序读取变量 nl 和 r
  4. 然后它循环地从输入读取 n 个整数到数组 a.
  5. 对数组进行排序。
  6. 最后打印出两个工作函数的差值结果。

让我们分析一下这段程序更详细的行为:

  • 数组长度为 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] 内有效配对数量。

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值