555 字
3 分钟
cf round 995
NOTE
D - Counting Pairs
关键词:二分
思路
题目要求找出一对下标 ,满足 ,且在删去这两个数后,剩余元素的和在 之间。
假设整个数组所有元素的总和为 。如果我们删去 和 ,剩余元素的和就是 。
根据题意,我们需要满足:
我们对这个不等式进行移项,把未知的 提取出来:
-
先两边减去 :
-
两边同时乘 :
令 ,。现在,问题就转换成了:在一个数组中,寻找有多少对元素的和落在给定的区间 内。
枚举每一个元素 ,对于当前元素 ,我们需要在它之后的元素中找出有多少个元素 满足 ,先排序,后用二分查找即可。
NOTE注意
std::accumulate的返回值和累加过程的类型取决于第三个参数,所以应该传0LL。
Code
// Problem: CF 2051 D// Contest: Codeforces - Codeforces Round 995 (Div. 3)// URL: https://codeforces.com/contest/2051/problem/D// Time: 2026-05-17 23:27:47#include <bits/stdc++.h>using namespace std;
// clang-format off#define endl '\n'#define all(x) (x).begin(), (x).end()#define fastio() ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);// clang-format on
using ll = long long;using ull = unsigned long long;using pii = pair<int, int>;using pdd = pair<double, double>;using pll = pair<long long, long long>;using i128 = __int128;
const int dx[] = {-1, 0, 1, 0, -1, 1, 1, -1};const int dy[] = {0, 1, 0, -1, 1, 1, -1, -1};const int inf = 0x3f3f3f3f;const int N = 2e5 + 10;
ll a[N];
void solve(){ ll n, x, y; cin >> n >> x >> y;
for (int i = 1; i <= n; i++) cin >> a[i];
ll sum = accumulate(a + 1, a + n + 1, 0LL);
sort(a + 1, a + n + 1);
ll res = 0; for (int i = 1; i <= n; i++) { ll pos1 = lower_bound(a + i + 1, a + n + 1, sum - a[i] - y) - a; ll pos2 = upper_bound(a + i + 1, a + n + 1, sum - a[i] - x) - a - 1;
if (pos1 <= pos2) res += pos2 - pos1 + 1; }
cout << res << endl;}
int main(){ fastio();
int T = 1; cin >> T;
while (T--) solve();
return 0;}