ps | |
---|---|
링크 | acmicpc.net/… |
출처 | BOJ |
문제 번호 | 31415 |
문제명 | UFO 침공 |
레벨 | 플래티넘 2 |
분류 |
이모스법 |
시간복잡도 | O(n + l*sqrt(n) + q) |
인풋사이즈 | n<=100,000, q<=100,000, l<=100,000 |
사용한 언어 | Python 3.11 |
제출기록 | 147688KB / 5792ms |
최고기록 | 5792ms |
해결날짜 | 2024/02/23 |
출처 |
"""Solution code for "BOJ 31415. UFO 침공".
- Problem link: https://www.acmicpc.net/problem/31415
- Solution link: http://www.teferi.net/ps/problems/boj/31415
Tags: [imos]
"""
import collections
import sys
def update(x, dx, max_x, x_counts, x_diffs, T):
if dx == 0:
if x <= max_x + 1:
x_counts[x] += 1
return
beg = x
if dx < 0:
dx = -dx
beg -= dx * (T - 1)
if beg > max_x + 1:
return
diffs = x_diffs[dx, x % dx]
diffs.append((max(beg, x % dx), 1))
end = beg + dx * T
if end <= max_x + 1:
diffs.append((end, -1))
def calc(x_diffs, x_counts, max_x):
for (dx, x), diff in x_diffs.items():
delta = 0
for p, d in sorted(diff):
while x < p:
x_counts[x] += delta
x += dx
delta += d
while x <= max_x:
x_counts[x] += delta
x += dx
def main():
N, Q, T = [int(x) for x in sys.stdin.readline().split()]
ufos = [[int(x) for x in sys.stdin.readline().split()] for _ in range(N)]
queries = [[int(x) for x in sys.stdin.readline().split()] for _ in range(Q)]
max_y = max((pos for t, pos in queries if t == 1), default=0)
max_x = max((pos for t, pos in queries if t == 2), default=0)
x_diffs = collections.defaultdict(list)
y_diffs = collections.defaultdict(list)
x_counts = [0] * (max_x + 1)
y_counts = [0] * (max_y + 1)
for x, y, dx, dy in ufos:
update(x, dx, max_x, x_counts, x_diffs, T)
update(y, dy, max_y, y_counts, y_diffs, T)
calc(x_diffs, x_counts, max_x)
calc(y_diffs, y_counts, max_y)
for t, pos in queries:
print(y_counts[pos] if t == 1 else x_counts[pos])
if __name__ == '__main__':
main()