Codeforces Round 995 (Div. 3)(补题)
Codeforces Round 995 (Div. 3)
D. Counting Pairs(离散化+二分)
题目描述
给你一个由
如果满足以下条件,一对整数
;- 如果同时从序列
中删除位置 和 的元素,则剩余元素的和至少为 ,最多为 。
你的任务是确定给定序列
输入
第一行包含一个整数
每个测试用例包含两行:
- 第一行包含三个整数
( , ); - 第二行包含
个整数 ( )。
输入的附加限制:所有测试用例中
输出
对于每个测试用例,输出一个整数 - 给定序列
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
思路
首先是推公式
设序列为数组
, 设 则
可以得到:
所以,我们可以枚举
得到 的范围,进而计算出 的个数,查找范围可以二分,但是由于数据范围太大,正常的二分肯定不行,所以要对数据进行离散化处理。
要注意的是前前后后并没有判断和 的大小关系,所以 、 、 的答案都会计算出来,只需要最后减去后面两个就行
评述:
非常有参考价值的一道题,值得多想
代码
#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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步