D - Make Target 2 Editorial by en_translator
To conveniently handle the expression \(\max(|x|, |y|)\), we count those with \(|x| > |y|\) and \(|x| \leq |y|\), and finally sum them up to find the answer.
Here, we will describe how to count those with \(|x| > |y|\). Those with \(|x| \leq |y|\) can be counted likewise.
When \(|x| > |y|\), \(\max(|x|, |y|) = |x|\). Thus, we may iterate all even numbers \(x\) within \(L \leq x \leq R\), and for each \(x\) find the number of \(y\) with \(|x| > |y|\) and \(D \leq y \leq U\). Since \(|x| > |y|\) is equivalent to \(-|x| < y < |x|\), for a fixed \(x\) the integers \(y\) to be counted are within \(\max(-|x| + 1, D) \leq y \leq \min(|x| - 1, U)\). The number of such \(y\) can be represented as \(\max(0, \min(|x| - 1, U) - \max(-|x| + 1, D) + 1)\), which can be computed in \(O(1)\) time for each \(x\). Hence, those with \(|x| > |y|\) can be counted in \(O(X)\) time, where \(X = R - L\).
Sample code
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
int l, r, d, u;
cin >> l >> r >> d >> u;
ll ans = 0;
// |x| > |y|
for (int x = l; x <= r; x++) {
if (x % 2 == 0) {
int D = max(d, -abs(x) + 1);
int U = min(u, abs(x) - 1);
int C = U - D + 1;
ans += max(C, 0);
}
}
// |x| <= |y|
for (int y = d; y <= u; y++) {
if (y % 2 == 0) {
int L = max(l, -abs(y));
int R = min(r, abs(y));
int C = R - L + 1;
ans += max(C, 0);
}
}
cout << ans << '\n';
}
posted:
last update: