ABC131 C - Anti-Division
備忘録
問題
回答
import sys import os import fractions MOD = 10 ** 9 + 7 def lcm(x, y): return (x * y) // fractions.gcd(x, y) def main(): if os.getenv("LOCAL"): sys.stdin = open("input.txt", "r") A, B, C, D = list(map(int, sys.stdin.readline().split())) E = B - A + 1 ret = 0 ret += B // C ret += B // D ret -= (A - 1) // C ret -= (A - 1) // D ret -= B // lcm(C, D) ret += (A-1) // lcm(C, D) print(E - ret) if __name__ == '__main__': main()
考え方
対象となる整数の数(B-A+1
)から割り切れる整数の数を引くことで、
答えを求めることが出来る。
例えば、下記のようなinput
の場合、
10 40 6 8
A = 10, B = 40, C = 6, D = 8
とすると、
- 対象となる整数が
10 ~ 40
の31
個(E = B - A + 1
) 40
以下の整数を対象に、6
で割り切ることが出来る整数の数は40 // 6
で6
個(B // C
)- そのうち、対象外の
9
以下の整数を6
で割り切ることが出来る整数の数は9 // 6
で1
個((A - 1) // C
)- つまり、対象となる整数
10 ~ 40
の31
個のうち、6
で割り切ることが出来る整数の数は5
個(6 - 1
)
- つまり、対象となる整数
- そのうち、対象外の
40
以下の整数を対象に、8
で割り切ることが出来る整数の数は40 // 8
で5
個(B // D
)- そのうち、対象外の
9
以下の整数を8
で割り切ることが出来る整数の数は9 // 8
で1
個((A - 1) // D
)- つまり、対象となる整数
10 ~ 40
の31
個のうち、8
で割り切ることが出来る整数の数は4
個(5 - 1
)
- つまり、対象となる整数
- そのうち、対象外の
40
以下の整数を対象に、6
と8
の最小公倍数24
で割り切ることが出来る整数の数は40 // 24
で1
個(B // lcm(C, D)
)- そのうち、対象外の
9
以下の整数を6
と8
の最小公倍数24
で割り切ることが出来る整数の数は9 // 24
で0
個((A-1) // lcm(C, D)
)
- そのうち、対象外の
以上の計算を元に、
対象となる整数の数から、
6
で割り切ることが出来る整数の数を減算、
8
で割り切ることが出来る整数の数を減算、
6
と8
で割り切ることが出来る整数の数を減算することで、
以下のように、
31 - ((6 - 1) + (5 - 1) - (1 + 0)) = 23
対象の整数の数は23
個と求めることが出来る