2024-12-23 21:29阅读: 247评论: 1推荐: 1

Codeforces Round 995 (Div. 3)(补题)

Codeforces Round 995 (Div. 3)

D. Counting Pairs(离散化+二分)

题目描述

给你一个由 n 个整数组成的序列 a ,其中序列的 i -th 元素等于 ai 。同时还给出两个整数 xy ( xy )。

如果满足以下条件,一对整数 (i,j) 就会被认为是有趣的:

  • 1i<jn ;
  • 如果同时从序列 a 中删除位置 ij 的元素,则剩余元素的和至少为 x ,最多为 y

你的任务是确定给定序列 a​ 中有趣的整数对的数目。

输入

第一行包含一个整数 t ( 1t104 ) - 测试用例数。

每个测试用例包含两行:

  • 第一行包含三个整数 n,x,y ( 3n2105 , 1xy21014 );
  • 第二行包含 n 个整数 a1,a2,,an ( 1ai109 )。

输入的附加限制:所有测试用例中 n 的总和不超过 2105

输出

对于每个测试用例,输出一个整数 - 给定序列 a 中有趣的整数对的数量。

Example

Input

7
4 8 10
4 6 3 6
6 22 27
4 9 6 3 4 5
3 8 10
3 2 1
3 1 1
2 3 4
3 3 6
3 2 1
4 4 12
3 3 2 1
6 8 8
1 1 2 2 2 3

Output

4
7
0
0
1
5
6

思路

首先是推公式

设序列为数组A, 设S=1nA[i]

xSA[i]A[j]y

可以得到:SyA[i]A[j]SxA[i]

所以,我们可以枚举A[i]得到A[j]的范围,进而计算出A[j]的个数,查找范围可以二分,但是由于数据范围太大,正常的二分肯定不行,所以要对数据进行离散化处理。
要注意的是前前后后并没有判断ij的大小关系,所以i<ji=ji>j的答案都会计算出来,只需要最后减去后面两个就行

评述:

非常有参考价值的一道题,值得多想

代码

#include <bits/stdc++.h>
typedef std::pair<int, int> pii;
#define INF 0x3f3f3f3f
#define MOD 998244353
using i64 = long long;
const int N = 1e5+5;
void solve(){
i64 n, x, y;
std::cin >> n >> x >> y;
i64 S = 0;
std::vector<i64> A(n), B(3*n+1);
std::vector<i64> dct;
dct.push_back(-1E18); // 防止越界加的哨兵
for (int i = 0; i < n; i++) {
std::cin >> A[i];
S += A[i];
}
for (int i = 0; i < n; i++){
dct.emplace_back(A[i]);
dct.emplace_back(S - x - A[i]);
dct.emplace_back(S - y - A[i]);
}
sort(dct.begin(), dct.end());
dct.erase(std::unique(dct.begin(), dct.end()), dct.end());
auto find = [&](i64 p) -> i64{
return std::lower_bound(dct.begin(), dct.end(), p) - dct.begin();
};
for (int i = 0; i < n; i++){
B[find(A[i])] += 1;
}
for (int i = 1; i < 3*n+1; i++){
B[i] += B[i-1];
}
i64 res = 0, ans = 0;
for (int i = 0; i < n; i++){
res += B[find(S-x-A[i])] - B[find(S-y-A[i]) - 1];
if (S - A[i] - A[i] >= x && S - A[i] - A[i] <= y) ans ++;
}
std::cout << (res - ans) / 2 << '\n';
}
signed main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2);
int t = 1, i;
std::cin >> t;
for (i = 0; i < t; i++){
solve();
}
return 0;
}

本文作者:califeee

本文链接:https://www.cnblogs.com/califeee/p/18625067

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   califeee  阅读(247)  评论(1编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.