목차

UFO 침공

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
출처

제3회 보라매컵 본선 Open Contest - H

풀이

코드

"""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()