D - AtCoder Wallpaper 解説 by evima
別の実装公式解説と同様に、\(4 \times 2\) の長方形が繰り返されていることに注目します。
まず、すべての座標に適当な値(\(10^9\) など)を足し、求めたい面積を変えることなく \(0 \leq A, 0 \leq C\) を成り立たせます。
この条件のもとで問題の答えを \(f(A, B, C, D)\) と書くと、これは \(f(0, 0, C, D) - f(0, 0, C, B) - f(0, 0, A, D) + f(0, 0, A, B)\) として求められます(キーワード:二次元累積和)。
あとは \(f(0, 0, A, B)\) が求められればよく、直線 \(x = 4 \cdot \lfloor \frac{A}{4} \rfloor\) と \(y = 2 \cdot \lfloor \frac{B}{2} \rfloor\) で四つのエリアに分割すれば、同じ長方形パターンの繰り返しとして計算できます。\(4 \times 2\) の長方形パターンの二次元累積和を手で構築しておくと便利です。
実装例:(Python)
def f(y, x):
a = [[0, 0, 0, 0, 0], [0, 2, 3, 3, 4], [0, 3, 6, 7, 8]]
sub1 = (y // 2) * (x // 4) * a[2][4]
sub2 = (y // 2) * a[2][x % 4]
sub3 = (x // 4) * a[y % 2][4]
sub4 = a[y % 2][x % 4]
return sub1 + sub2 + sub3 + sub4
M = 10**9
A, B, C, D = map(lambda x: int(x) + M, input().split())
print(f(D, C) - f(D, A) - f(B, C) + f(B, A))
投稿日時:
最終更新: