公式

D - Make Target 2 解説 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';
}

投稿日時:
最終更新: