2 条题解
-
0
- 双指针实现
- 请大家自己动手写一遍!!!
#include <bits/stdc++.h> using namespace std; using i64 = long long; // i < j && a[i] + a[j] <= m 的 (i, j) 的对数 // 相向双指针 i64 addle(const vector<int>& a, int m) { i64 ans = 0, n = a.size(); for (int l = 0, r = n; l < n; l++) { r = max(l + 1, r); // a[r] 是 l 右边第一个使得 a[l] + a[r] > m 的数 while (r - 1 > l && a[r - 1] + a[l] > m) r--; // 那么从 a[l + 1] 到 a[r - 1] 都满足要求 ans += r - 1 - l; } return ans; } // i < j && a[i] + a[j] >= m 的 (i, j) 的对数 // 相向双指针 i64 addge(const vector<int>& a, int m) { i64 ans = 0, n = a.size(); for (int l = 0, r = n; l < n; l++) { r = max(l + 1, r); // a[r] 是 l 右边第一个使得 a[l] + a[r] >= m 的数 while (r - 1 > l && a[r - 1] + a[l] >= m) r--; // 那么从 a[r] 到 a[n - 1] 都满足要求 ans += n - r; } return ans; } // i < j && a[j] - a[j] <= m 的 (i, j) 的对数 // 同向双指针 i64 delle(const vector<int>& a, int m) { i64 ans = 0, n = a.size(); for (int l = 0, r = 0; l < n; l++) { r = max(l + 1, r); // a[r] 是 l 右边第一个使得 a[r] - a[l] > m 的数 while (r < n && a[r] - a[l] <= m) r++; // 那么从 a[l + 1] 到 a[r - 1] 都满足要求 ans += r - 1 - l; } return ans; } // i < j && a[j] - a[j] >= m 的 (i, j) 的对数 // 同向双指针 i64 delge(const vector<int>& a, int m) { i64 ans = 0, n = a.size(); for (int l = 0, r = 0; l < n; l++) { r = max(l + 1, r); // a[r] 是 l 右边第一个使得 a[r] - a[l] >= m 的数 while (r < n && a[r] - a[l] < m) r++; // 那么从 a[r] 到 a[n - 1] 都满足要求 ans += n - r; } return ans; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n, l, r; cin >> n >> l >> r; vector<int> a(n); for (int i = 0; i < n; i++) cin >> a[i]; sort(a.begin(), a.end()); // (a[i] + a[j] >= l 的对数) - (a[i] + a[j] >= r + 1 的对数) cout << addge(a, l) - addge(a, r + 1) << '\n'; // 下面的也可以 // (a[i] + a[j] <= r 的对数) - (a[i] + a[j] <= l - 1 的对数) // cout << addle(a, r) - addle(a, l - 1) << '\n'; return 0; } -
0
lower_bound和upper_bound实现- 请大家自己动手写一遍!!!
#include <bits/stdc++.h> using namespace std; using i64 = long long; // i < j && a[i] + a[j] <= m 的 (i, j) 的对数 i64 addle(const vector<int>& a, int m) { i64 ans = 0, n = a.size(); for (int l = 0; l < n; l++) { // a[r] 是 l 右边第一个使得 a[l] + a[r] > m 的数 int r = upper_bound(a.begin() + l + 1, a.end(), m - a[l]) - a.begin(); // 那么从 a[l + 1] 到 a[r - 1] 都满足要求 ans += r - 1 - l; } return ans; } // i < j && a[i] + a[j] >= m 的 (i, j) 的对数 i64 addge(const vector<int>& a, int m) { i64 ans = 0, n = a.size(); for (int l = 0; l < n; l++) { // a[r] 是 l 右边第一个使得 a[l] + a[r] >= m 的数 int r = lower_bound(a.begin() + l + 1, a.end(), m - a[l]) - a.begin(); // 那么从 a[r] 到 a[n - 1] 都满足要求 ans += n - r; } return ans; } // i < j && a[j] - a[j] <= m 的 (i, j) 的对数 // 同向双指针 i64 delle(const vector<int>& a, int m) { i64 ans = 0, n = a.size(); for (int l = 0; l < n; l++) { // a[r] 是 l 右边第一个使得 a[r] - a[l] > m 的数 int r = upper_bound(a.begin() + l + 1, a.end(), m + a[l]) - a.begin(); // 那么从 a[l + 1] 到 a[r - 1] 都满足要求 ans += r - 1 - l; } return ans; } // i < j && a[j] - a[j] >= m 的 (i, j) 的对数 // 同向双指针 i64 delge(const vector<int>& a, int m) { i64 ans = 0, n = a.size(); for (int l = 0; l < n; l++) { // a[r] 是 l 右边第一个使得 a[r] - a[l] >= m 的数 int r = lower_bound(a.begin() + l + 1, a.end(), m + a[l]) - a.begin(); // 那么从 a[r] 到 a[n - 1] 都满足要求 ans += n - r; } return ans; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n, l, r; cin >> n >> l >> r; vector<int> a(n); for (int i = 0; i < n; i++) cin >> a[i]; sort(a.begin(), a.end()); // (a[i] + a[j] >= l 的对数) - (a[i] + a[j] >= r + 1 的对数) cout << addge(a, l) - addge(a, r + 1) << '\n'; // 下面的也可以 // (a[i] + a[j] <= r 的对数) - (a[i] + a[j] <= l - 1 的对数) // cout << addle(a, r) - addle(a, l - 1) << '\n'; return 0; }
- 1
信息
- ID
- 424
- 时间
- 100ms
- 内存
- 32MiB
- 难度
- 5
- 标签
- 递交数
- 57
- 已通过
- 24
- 上传者