백준 문제풀이

백준 17634 - 이상한 기계 [Python]

Vermeil 2022. 4. 19. 02:33

https://www.acmicpc.net/problem/17634

 

17634번: 이상한 기계

첫 번째 테스트에서, 이 기계는 시점 4에서 (2, 1)을, 시점 7에서 (0, 1)을, 시점 8에서 (1, 2)를, 시점 9 에서 (0, 0)를, 시점 17에서 (1, 2)를, 시점 18에서 (0, 0)를 출력한다. 따라서 서로 다른 네 개의 순서

www.acmicpc.net

[사용한 알고리즘]

라인 스위핑, 정수론

 

greedev에게 APIO 문제를 추천해달라고 해서 받은 문제다.

 

 

간단하고 재미있는 식정리이다.

 

\(t = Bp + q\) (p, q 서로소 아님) 으로 두면,

\(x = ((B + 1)p + q) \hspace{0.15cm} mod \hspace{0.15cm} A\)

\(y = q\)

가 된다.

 

\(q = 0\)으로 두면,

\(x\)의 주기는 \(\frac{A}{gcd(A, B + 1)}\)이고,

\(y\)의 주기는 \(B\)이다.

이 둘을 곱한 값인 \(\frac{AB}{gcd(A, B + 1)}\)가 순서쌍의 주기이므로, 주기를 \(m\)이라고 할 때 \(t \hspace{0.15cm} mod \hspace{0.15cm} m\)의 서로 다른 값의 개수를 찾으면 된다.

 

\([l, r]\)을 \([l \hspace{0.15cm} mod \hspace{0.15cm} m, r \hspace{0.15cm} mod \hspace{0.15cm} m]\)으로 바꾸고 라인스위핑을 하면 끝이다.

 

74줄부터 보면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import sys, math
import heapq
 
from dataclasses import dataclass
from collections import deque
from bisect import bisect_left, bisect_right
 
input = sys.stdin.readline
 
hqp = heapq.heappop
hqs = heapq.heappush
 
 
# input
def ip(): return int(input())
def sp(): return str(input().rstrip())
 
def mip(): return map(int, input().split())
def msp(): return map(str, input().split().rstrip())
 
def lmip(): return list(map(int, input().split()))
def lmsp(): return list(map(str, input().split()))
 
 
# gcd, lcm
def gcd(x, y):
    while y:
        x, y = y, x % y
    return x
 
 
def lcm(x, y):
    return x * y // gcd(x, y)
 
 
# prime
def isPrime(x):
    if x <= 1return False
    for i in range(2int(x ** 0.5+ 1):
        if x % i == 0:
            return False
    return True
 
 
# Union Find
# p = [i for i in range(n + 1)]
 
def find(x):
    if x == p[x]:
        return x
    q = find(p[x])
    p[x] = q
    return q
 
 
def union(x, y):
    x = find(x)
    y = find(y)
 
    if x != y:
        p[y] = x
 
 
def getPow(a, x):
    ret = 1
    while x:
        if x & 1:
            ret = (ret * a) % MOD
        a = (a * a) % MOD
        x >>= 1
    return ret
 
 
############### Main! ###############
 
n, A, B = mip()
= A // gcd(A, B + 1* B
= []
for i in range(n):
    l, r = mip()
    if r - l >= m:
        print(m)
        exit()
 
    if l % m > r % m:
        a.append([l % m, m - 1])
        a.append([0, r % m])
    else:
        a.append([l % m, r % m])
a.sort()
ans = 0
= a[0][0]
= a[0][1]
for i in range(1len(a)):
    nl = a[i][0]
    nr = a[i][1]
    if l <= nl and nr <= r:
        continue
    if r < nl:
        ans += r - l + 1
        l = nl
    r = nr
ans += r - l + 1
print(ans)
 
 
######## Priest greedev ########
 
cs