给一个长为 \(n\) 的数组 \(a\) ,统计出所有二元组 \((a_i, a_j)\) 数量,满足以下条件:
- \(1 \leq j < i \leq n, |a_i - a_j| = max_{1 \leq p,q \leq n} |a_{p} - a_{q}|\)
显然贡献不绑定位置,且考虑绝对值的情况,数组排序后去除绝对值。
此时即统计出 \((a_i, a_j)\) 数量,满足
- \(1 \leq j < i \leq n, a_i - a_j = a_n - a_1\) 。
然后将这个数量乘以二即可,有序数组中选出的两个数可以在 \((a_i, a_j)\) 中任选一个位置。
取最左连续相同段 \(h\) ,最右连续相同段 \(w\) 。
- 若 \(h = n\) ,所有数相等,从 \(n\) 中任选两个 \(2 \cdot \binom{n}{2} = n(n-1)\) 。
- 若 \(h < n\) ,根据乘法原理答案为 \(2 \times h \cdot w\) 。
此题使用线性做法与排序做法差不多。
view
#include <bits/stdc++.h>
void solve() {
int n; std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; i++) std::cin >> a[i];
std::sort(a.begin(), a.end());
int l = 0; while (l + 1 < n && a[l+1]==a[l]) l++;
if (l == n - 1) {
std::cout << 1LL * n * (n - 1) << '\n';
return;
}
int r = n - 1; while (r - 1 >= 0 && a[r-1]==a[r]) --r;
std::cout << 2LL * (l + 1) * (n - r) << '\n';
}
int main() {
int _ = 1; std::cin >> _;
while (_--) { solve(); }
return 0;
}
- Combinatorics Codeforces Hossam Round 837combinatorics codeforces hossam round codeforces minimum hossam round combinatorics educational codeforces problem educational codeforces round rated codeforces round 911 div codeforces round 864 div codeforces round 887 div codeforces round 913 div codeforces round 863 div codeforces round 915 div