Computer Science/Algorithms

🏘️Euler Sieve

metamong 2024. 4. 21.

intro

🏘️ μ†Œμˆ˜ νŒμ •λ²•μœΌλ‘œ 유λͺ…ν•œ μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ 체(Sieve of Eratosthenes)λ₯Ό κ°œμ„ ν•œ '였일러의 체(Euler Sieve)'에 λŒ€ν•΄μ„œ μ†Œκ°œν•œλ‹€. μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ μ²΄λŠ” μ†Œμˆ˜ νŒλ³„ μ‹œκ°„ λ³΅μž‘λ„κ°€ O(nloglogn)μž„μ΄ μ•Œλ €μ Έ 있고, 이λ₯Ό κ°œμ„ ν•œ 였일러의 체 μ‹œκ°„ λ³΅μž‘λ„λŠ” 단 μ„ ν˜• μ‹œκ°„λ§Œμ— O(n)으둜 νŒλ³„μ΄ κ°€λŠ₯ν•˜λ‹€.

 

🏘️ μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ 체의 μ‹œκ°„ λ³΅μž‘λ„κ°€ μ„ ν˜• μ‹œκ°„(O(n))이 될 수 μ—†λŠ” μ΄μœ λŠ” ν•©μ„±μˆ˜ 210을 λ“€λ©΄ μ‰½κ²Œ μ•Œ 수 μžˆλ‹€. 210은 2x3x5x7둜 λ‚˜νƒ€λ‚Ό 수 μžˆλŠ”λ°, μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ 체에 μ˜ν•΄μ„œλŠ” 2x3x5x7 / 2x3x5x7 / 2x3x5x7 / 2x3x5x7 와 같이 각각 빨간색 숫자일 λ•Œ 210이 ν•©μ„±μˆ˜μž„μ„ μ€‘λ³΅ν•΄μ„œ μ•Œλ €μ£Όκ³  μžˆλ‹€.

 

🏘️ λ”°λΌμ„œ, 이λ₯Ό 단 ν•œλ²ˆμ— ν•©μ„±μˆ˜κ°€ μ•„λ‹˜μ„ μ•Œλ €μ£ΌκΈ° μœ„ν•΄ κ°œμ„ ν•œ μ•Œκ³ λ¦¬μ¦˜μ΄ Euler Sieve μ•Œκ³ λ¦¬μ¦˜μ΄κ³ , μ‹œκ°„ λ³΅μž‘λ„λŠ” O(n). λ”°λΌμ„œ μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ 체 λ³€ν˜• 판 'Linear Sieve'라 λΆ€λ₯΄κΈ°λ„ ν•œλ‹€. 였일러의 체λ₯Ό μ‹€ν–‰ν•˜λ©΄ Nμ΄ν•˜μ˜ 수의 β‘  각각 μžμ—°μˆ˜μ˜ μ΅œμ†Œ μ†ŒμΈμˆ˜ list(spf(smallest prime factor) list)와 β‘‘ μ†Œμˆ˜ listλ₯Ό 두 κ°œλ‚˜ 얻을 수 μžˆλ‹€. λ˜ν•œ, spf listλ₯Ό μ‚¬μš©ν•΄ β‘’ λΉ λ₯Έ μ†ŒμΈμˆ˜λΆ„ν•΄λ„ κ°€λŠ₯ν•˜λ‹€.

1. making an Euler Sieve

ex) N = 29 κ°€μ •

 

β‘  μ΄ˆκΈ°ν™”) 30개의 μˆ«μžκ°€ λ“€μ–΄κ°ˆ 수 μžˆλŠ” listλ₯Ό λ§Œλ“ λ‹€(index 0λΆ€ν„° μ‹œμž‘ν•˜λ―€λ‘œ 30개 μ€€λΉ„)

(1) 총 30개의 칸에 0λΆ€ν„° 29κΉŒμ§€μ˜ 숫자λ₯Ό μ°¨λ‘€λŒ€λ‘œ (index κ·ΈλŒ€λ‘œ) 집어 λ„£λŠ”λ‹€.

 

(2) 2 포함 29κΉŒμ§€μ˜ λͺ¨λ“  μ§μˆ˜λŠ” 2둜 λ°”κΎΌλ‹€. (λͺ¨λ“  μ§μˆ˜λŠ” 무쑰건 μ†ŒμΈμˆ˜λŠ” 2μ΄λ―€λ‘œ μ΄ˆκΈ°ν™” λ•Œ 미리 μ„€μ •ν•΄λ†“μŒ)

 

β˜† μ§μˆ˜λŠ” 전체 λ²”μœ„μ˜ μ ˆλ°˜μ΄λ‚˜ ν•΄λ‹Ήν•˜λ―€λ‘œ 미리 2둜 λ°”κΎΈλ©΄ 탐색 μ‹œκ°„ 쀄일 수 있음


(3) prime list에 2λΆ€ν„° λ„£κ³  μ€€λΉ„.

 

β‘‘ xλ₯Ό 3λΆ€ν„° floor(√N)κΉŒμ§€ ν™€μˆ˜λ§Œ λŒλ¦°λ‹€. (λŒλ¦¬λŠ” λ³€μˆ˜ x κ°€μ •) (μ•„λž˜ κ·Έλ¦Ό μ΄ˆλ‘μƒ‰ 숫자)

(배수만큼 O(N) μ‹œκ°„ λ³΅μž‘λ„λ‘œ searchingν•˜κΈ° λ•Œλ¬Έμ— 전체 NκΉŒμ§€ 돌릴 ν•„μš” x / λ˜ν•œ μ§μˆ˜λŠ” spf 무쑰건 2μ΄λ―€λ‘œ μƒλž΅. ν™€μˆ˜λ§Œ 돌림)

 

ex) 즉 xλ₯Ό 3ν•˜κ³  5만 λŒλ¦°λ‹€.

β‘’ sieve[x]κ°€ index λ‚˜ μžμ‹  x라면 (if sieve[x] == x), xλŠ” x보닀 μž‘μ€ 수의 λ°°μˆ˜μ—μ„œ κ±ΈλŸ¬μ§€μ§€ μ•Šμ•˜λ‹€λŠ” 의미, 즉 x의 μ•½μˆ˜λŠ” 1κ³Ό λ‚˜ μžμ‹ λ§Œ 있음이 증λͺ…λ˜μ—ˆκΈ°μ— μ†Œμˆ˜μž„μ΄ 증λͺ…됨. λ”°λΌμ„œ prime list에 λ„£λŠ”λ‹€

 

β‘£ κ·Έλ¦¬κ³  yλΌλŠ” λ³€μˆ˜λ₯Ό x*xλΆ€ν„° sieve λκΉŒμ§€ x*2 step으둜 λŒλ©΄μ„œ x의 배수(x μžμ‹  μ œμ™Έ)인 yλŠ” λͺ¨λ‘ ν•©μ„±μˆ˜(μ†Œμˆ˜μ˜ λ°°μˆ˜λŠ” λͺ¨λ‘ ν•©μ„±μˆ˜)μ΄λ―€λ‘œ μ†Œμˆ˜κ°€ μ•„λ‹ˆλ‹€. 이 λ•Œ sieve[y]κ°€ 이미 ν•©μ„±μˆ˜μž„μ΄ λ°ν˜€μ‘Œλ‹€λ©΄(sieve[y] != y) ν•΄λ‹Ή yλŠ” xκ°€ μ΅œμ†Œ μ†ŒμΈμˆ˜κ°€ μ•„λ‹ˆλ―€λ‘œ pass. sieve[y]κ°€ y둜 μ΄ˆκΈ°ν™”λœ μƒνƒœλ‘œ κ·ΈλŒ€λ‘œ μžˆλ‹€λ©΄ ν•΄λ‹Ή yλŠ” xκ°€ μ΅œμ†Œ μ†ŒμΈμˆ˜μ΄λ―€λ‘œ sieve[y] = x λ§ˆν‚Ή.

 

β˜† x*2κ°€ μ•„λ‹ˆλΌ x*xλΆ€ν„° λ„λŠ” μ΄μœ λŠ”, x*x μ΄ν•˜μ˜ x의 λ°°μˆ˜λŠ” spfλ₯Ό x둜 μ†ŒμΈμˆ˜λ₯Ό 가지지 μ•ŠκΈ° λ•Œλ¬Έ.

 

β˜† step을 xκ°€ μ•„λ‹ˆλΌ x*2둜 μ„€μ •ν•œ μ΄μœ λŠ”, xλ₯Ό μ§μˆ˜λ°°ν•œ μˆ«μžλŠ” 무쑰건 μ§μˆ˜κ°€ μ†ŒμΈμˆ˜λ‘œ λ“€μ–΄κ°€λ―€λ‘œ 2κ°€ spf이기 λ•Œλ¬Έ.

 

ex) xκ°€ 3일 λ•Œ, 3의 μ œκ³±λΆ€ν„° λκΉŒμ§€ 6μ”© step λŒλ©΄μ„œ 15, 21, 27에 3 λ§ˆν‚Ή

ex) xκ°€ 5μΌλ•Œ, 5의 μ œκ³±λΆ€ν„° λκΉŒμ§€ 10μ”© step λŒλ©΄μ„œ 25에 5 λ§ˆν‚Ή

 

β‘€ NκΉŒμ§€μ˜ spf list μ™„μ„±(μœ„ 였λ₯Έμͺ½ κ·Έλ¦Ό). spf list만 μ›ν•œλ‹€λ©΄ x의 λ²”μœ„λ₯Ό √N으둜 탐색해도 μΆ©λΆ„ν•˜λ‚˜, prime listκΉŒμ§€ μ›ν•œλ‹€λ©΄ NκΉŒμ§€ 탐색해 sieve[x] == x인 경우 μ°¨λ‘€λŒ€λ‘œ prime list에 λ„£μ–΄μ£Όλ©΄ λœλ‹€. 그럴 경우 prime listλŠ” [3, 5, 7, 11, 13, 17, 19, 23, 29] μ™„μ„±

2. Factorization

β‘  μœ„μ—μ„œ λ§Œλ“  spf listλ₯Ό ν™œμš©ν•΄ λΉ λ₯Έ μ†ŒμΈμˆ˜λΆ„ν•΄λ₯Ό 진행할 수 μžˆλ‹€. 예λ₯Ό λ“€μ–΄ numμ΄λΌλŠ” λ³€μˆ˜μ˜ μ†ŒμΈμˆ˜λΆ„ν•΄λ₯Ό μ§„ν–‰ν•œλ‹€λ©΄ num의 spf 값을 체크. λ‚˜ μžμ‹ μ΄λΌλ©΄ num이 μ†Œμˆ˜μ΄λ―€λ‘œ num ν•œ 개 좜λ ₯ν•˜λ©΄ 끝. 그렇지 μ•Šλ‹€λ©΄ num//spf κ°’μ˜ spf 값을 κ΅¬ν•΄λ‚˜κ°€λ©΄ λœλ‹€. λ”°λΌμ„œ num이 1이 될 λ•ŒκΉŒμ§€ num에 spfλ₯Ό λ‚˜λˆ„μ–΄λ‚˜κ°€λ©° factorization을 μ™„μ„±ν•΄λ‚˜κ°€λ©΄ λœλ‹€.

 

ex) num이 210이라면 spf[num](=spf[210])이 2μ΄λ―€λ‘œ 2 μ €μž₯ν•œ λ’€, 210을 2둜 λ‚˜λˆˆ 105λ₯Ό num으둜 μ„€μ • spf[num](spf[105])을 λ³΄λ‹ˆ 3μ΄λ―€λ‘œ 3 μ €μž₯ν•œ λ’€, 3으둜 λ‚˜λˆˆ 35λ₯Ό num으둜 μ„€μ •. spf[35]λŠ” 5μ΄λ―€λ‘œ 5 μ €μž₯ν•˜κ³  7을 num으둜 μ„€μ •. spf[7]은 7μ΄λ―€λ‘œ 7 μ €μž₯ν•˜κ³  1을 num으둜 μ„€μ •. num이 1이 λ˜μ—ˆμœΌλ―€λ‘œ μ’…λ£Œ.

 

ex) num = 27일 λ•Œ μ†ŒμΈμˆ˜λ₯Ό μ°ΎλŠ” 과정을 그림으둜 λ‚˜νƒ€λ‚΄λ©΄ μ•„λž˜μ™€ κ°™λ‹€.

: λ…Έλž€μƒ‰ λ°•μŠ€κ°€ 27의 μ†ŒμΈμˆ˜λ‘œ 3, 3, 3μž„μ„ λ°”λ‘œ μ•Œ 수 μžˆλ‹€.

code

β‘  linear sieve μ™„μ„± μ½”λ“œ(nκΉŒμ§€μ˜ spf list)

#linear sieve
sieve = [i for i in range(n+1)]
sieve[4::2] = [2]*(math.ceil((len(sieve)-4)/2))

for x in range(3,(int(len(sieve)**(1/2)))+1,2):
    if sieve[x] == x:
        for y in range(x*x,len(sieve),x*2):
            if sieve[y] == y:
                sieve[y] = x

 

β‘‘ factorization μ½”λ“œ(num μ†ŒμΈμˆ˜λΆ„ν•΄)

ans=[]
while num > 1:
    ans.append(spf[num])
    num//=spf[num]
print(*ans)

examples

β˜… <λ°±μ€€ G4 16563 μ–΄λ €μš΄ μ†ŒμΈμˆ˜λΆ„ν•΄> β˜… 문제 링크

Q. 말 κ·ΈλŒ€λ‘œ μž…λ ₯ν•œ μˆ˜λ“€μ˜ μ†ŒμΈμˆ˜λΆ„ν•΄λ₯Ό 진행해 λͺ¨λ“  μ†ŒμΈμˆ˜λ“€μ„ 각각 좜λ ₯ν•΄μ£ΌλŠ” 문제. N의 λ²”μœ„κ°€ 5λ°±λ§ŒκΉŒμ§€μ΄λ―€λ‘œ euler sieve ν™œμš©

 

β˜… <λ°±μ€€ G2 3142 즐거운 삢을 μœ„ν•œ λ…Έλ ₯> β˜… 문제 링크

Q. μ™„μ „μ œκ³±μˆ˜ μ—¬λΆ€λ₯Ό μ†ŒμΈμˆ˜ μ’…λ₯˜λ³„ 짝수 κ°œμˆ˜μΈμ§€ νŒλ‹¨ν•˜λŠ” 문제. μ†ŒμΈμˆ˜ μ’…λ₯˜κ°€ λ“€μ–΄κ°„ set() μžλ£Œν˜• λ§Œλ“€κ³  μž…λ ₯ν•œ 숫자의 μ†ŒμΈμˆ˜κ°€ set에 μ—†λ‹€λ©΄ μ‚½μž…. μžˆλ‹€λ©΄ set()에 μ‘΄μž¬ν•˜λŠ” μ†ŒμΈμˆ˜ μ—†μ• λŠ” λ°©μ‹μœΌλ‘œ 진행해 set에 λ‚¨λŠ” μ†ŒμΈμˆ˜ 여뢀에 따라 μ™„μ „μ œκ³±μˆ˜ νŒλ³„ν•˜λŠ” 문제

'Computer Science > Algorithms' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

πŸ₯Counting Sort  (0) 2024.04.17
πŸ—ΌTower of Hanoi  (0) 2024.04.09
βž•Merge Sort  (0) 2024.04.06
🍑 Two Pointers  (1) 2024.02.11
🦜 Pigeonhole Principle  (0) 2024.02.02

λŒ“κΈ€