Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

21-janghw0126 #89

Merged
merged 4 commits into from
Mar 10, 2024
Merged

21-janghw0126 #89

merged 4 commits into from
Mar 10, 2024

Conversation

janghw0126
Copy link
Member

@janghw0126 janghw0126 commented Mar 5, 2024

πŸ”— 문제 링크

λ°±μ€€ | μ•½μˆ˜μ˜ ν•©

문제 μ„€λͺ…

두 μžμ—°μˆ˜ A와 Bκ°€ μžˆμ„ λ•Œ, A = BCλ₯Ό λ§Œμ‘±ν•˜λŠ” μžμ—°μˆ˜ Cλ₯Ό A의 μ•½μˆ˜λΌκ³  ν•œλ‹€. 예λ₯Ό λ“€μ–΄, 2의 μ•½μˆ˜λŠ” 1, 2κ°€ 있고, 24의 μ•½μˆ˜λŠ” 1, 2, 3, 4, 6, 8, 12, 24κ°€ μžˆλ‹€. μžμ—°μˆ˜ A의 μ•½μˆ˜μ˜ 합은 A의 λͺ¨λ“  μ•½μˆ˜λ₯Ό λ”ν•œ 값이고, f(A)둜 ν‘œν˜„ν•œλ‹€. x보닀 μž‘κ±°λ‚˜ 같은 λͺ¨λ“  μžμ—°μˆ˜ y의 f(y)값을 λ”ν•œ 값은 g(x)둜 ν‘œν˜„ν•œλ‹€. μžμ—°μˆ˜ N이 μ£Όμ–΄μ‘Œμ„ λ•Œ, g(N)을 κ΅¬ν•΄λ³΄μž.

μž…λ ₯

  • 첫째 쀄에 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ˜ 개수 T($1 ≀ T ≀ 100,000$)κ°€ 주어진닀.
  • λ‘˜μ§Έ 쀄뢀터 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€κ°€ ν•œ 쀄에 ν•˜λ‚˜μ”© 주어지며 μžμ—°μˆ˜ N($1 ≀ N ≀ 1,000,000$)이 주어진닀.

좜λ ₯

  • 각각의 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€λ§ˆλ‹€, ν•œ 쀄에 ν•˜λ‚˜μ”© g(N)λ₯Ό 좜λ ₯ν•œλ‹€.

βœ”οΈ μ†Œμš”λœ μ‹œκ°„

ν•˜λ£¨(집쀑λ ₯ λ°”λ‹₯ 이슈...πŸ˜…) + 1μ‹œκ°„ 반

✨ μˆ˜λ„ μ½”λ“œ

βœ…μ΄ λ¬Έμ œμ—μ„œλŠ” μ•½μˆ˜λ₯Ό κ΅¬ν•˜λŠ” 방법이 핡심이닀. 일단 μ•½μˆ˜λ₯Ό κ΅¬ν•˜λŠ” 방법은 두 κ°€μ§€λ‘œ ꡬ뢄할 수 μžˆλ‹€.

  1. μžμ—°μˆ˜ N이 μ£Όμ–΄μ‘Œμ„ λ•Œ, 1λΆ€ν„° NκΉŒμ§€ λ‚˜λˆ„μ–΄κ°€λ©΄μ„œ λ‚˜λ¨Έμ§€κ°€ 0인 값을 κ΅¬ν•˜λŠ” 방법
  2. μžμ—°μˆ˜ N이 μ£Όμ–΄μ‘Œμ„ λ•Œ, μ•½μˆ˜λŠ” μ„œλ‘œ λŒ€μΉ­ ꡬ쑰λ₯Ό 이루고 μžˆμœΌλ―€λ‘œ 1λΆ€ν„° A의 μ œκ³±κ·ΌκΉŒμ§€μ˜ μ•½μˆ˜λ₯Ό κ΅¬ν•˜λŠ” 방법

ν•˜μ§€λ§Œ 이 λ¬Έμ œμ—μ„œλŠ” μ‹œκ°„ μ œν•œμ΄ 1μ΄ˆμ΄λ―€λ‘œ μ‹œκ°„ λ³΅μž‘λ„κ°€ 그보닀 큰 μœ„μ—μ„œ λ§ν•œ 두 가지 방법을 μ‚¬μš©ν•  수 μ—†λ‹€.
κ·Έλž˜μ„œ λ‹€λ₯Έ 아이디어λ₯Ό μƒκ°ν•΄λ³΄λŠ” 도쀑에 배수λ₯Ό μ΄μš©ν•œ 방법을 μƒκ°ν•΄λ³΄μ•˜λ‹€.
예λ₯Ό λ“€μ–΄, 4의 λ°°μˆ˜λŠ” 4,8,12, ... 이닀. κ·ΈλŸ¬λ‹ˆκΉŒ 4의 λ°°μˆ˜λŠ” 4λ₯Ό μ•½μˆ˜λ‘œ κ°–λŠ”λ‹€. λ‹€λ₯Έ μˆ˜λ“€λ„ λ§ˆμ°¬κ°€μ§€μ΄λ―€λ‘œ 결둠을 내보면, N의 λ°°μˆ˜λŠ” N을 항상 μ•½μˆ˜λ‘œ κ°–λŠ”λ‹€.

κ·ΈλŸ¬λ―€λ‘œ Nμ΄ν•˜μ˜ μžμ—°μˆ˜ μ€‘μ—μ„œ iλ₯Ό μ•½μˆ˜λ‘œ κ°–λŠ” κ°―μˆ˜λŠ” N/i개라고 ν•  수 μžˆλ‹€.

$g(N)=1Γ—N/1+2Γ—N/2+...+NΓ—N/N$

이런 원리λ₯Ό λ°”νƒ•μœΌλ‘œ 문제λ₯Ό ν•΄κ²°ν•˜λ©΄ λ¬΄λ‚œν•˜κ²Œ 톡과될 것 κ°™μ•˜λ‹€!

πŸ“–μ²« 번째 μ‹œλ„ 방법

  1. μ •μˆ˜ 값을 μž…λ ₯λ°›λŠ”λ‹€.
  2. 각 ν…ŒμŠ€νŠΈ 데이터λ₯Ό μž…λ ₯받을 λ•Œλ§ˆλ‹€ 1λΆ€ν„° λ°˜λ³΅ν•˜λ©΄μ„œ λ‚˜λˆ„μ–΄ 떨어지면 ν•©ν•œλ‹€.
  3. 각각의 λ°˜λ³΅μ—μ„œ N을 μž…λ ₯ λ°›λŠ”λ‹€.
  4. g(N)인 total_sum을 μ΄ˆκΈ°ν™”ν•œλ‹€.
  5. 1λΆ€ν„° μ‹œμž‘ν•΄μ„œ NκΉŒμ§€μ˜ 수λ₯Ό μˆœμ„œλŒ€λ‘œ λŒ€μž…ν•˜λ©΄μ„œ λ°˜λ³΅λ¬Έμ„ μ‹€ν–‰ν•œλ‹€.
  6. N을 test둜 λ‚˜λˆˆ λͺ«μ„ κ΅¬ν•œ 뒀에 testλ₯Ό κ³±ν•΄μ„œ total_sum에 λ”ν•œλ‹€.

⬇️전체 μ½”λ“œ

import sys
input=sys.stdin.readline
# μ •μˆ˜ 값을 μž…λ ₯λ°›λŠ”λ‹€.
T=int(input())

#각 ν…ŒμŠ€νŠΈ 데이터λ₯Ό μž…λ ₯받을 λ•Œλ§ˆλ‹€ 1λΆ€ν„° λ°˜λ³΅ν•˜λ©΄μ„œ λ‚˜λˆ„μ–΄ 떨어지면 ν•©ν•œλ‹€.
for _ in range(T):
    # 각각의 λ°˜λ³΅μ—μ„œ N을 μž…λ ₯λ°›λŠ”λ‹€.
    N=int(input())
    # g(N)인 total_sum을 μ΄ˆκΈ°ν™”ν•œλ‹€.
    total_sum=0
    # 1λΆ€ν„° μ‹œμž‘ν•΄μ„œ NκΉŒμ§€μ˜ 수λ₯Ό μˆœμ„œλŒ€λ‘œ λŒ€μž…ν•˜λ©΄μ„œ λ°˜λ³΅λ¬Έμ„ μ‹€ν–‰ν•œλ‹€.
    for test in range(1,N+1):
        # N을 test둜 λ‚˜λˆˆ λͺ«μ„ κ΅¬ν•œ 뒀에 testλ₯Ό κ³±ν•΄μ„œ total_sum에 λ”ν•œλ‹€.
        total_sum+=(N//test)*test
    print(total_sum)

μ΄λ ‡κ²Œ μ œμΆœν•˜μ˜€λ”λ‹ˆ
image
μ‹œκ°„ μ΄ˆκ³Όκ°€ λ–΄λ‹€.....
μ™œ κ·ΈλŸ°μ§€ ν•˜λ£¨ 쒅일 λΆ™μž‘κ³  생각해봐도 λ„μ €νžˆ 닡이 λ– μ˜€λ₯΄μ§€ μ•Šμ•„ μ°Ύμ•„λ³΄λ‹ˆ λ°±μ€€ μ•Œκ³ λ¦¬μ¦˜μ˜ 경우 μ‹œκ°„ λ³΅μž‘λ„κ°€ $O(n^2)$일 땐 2000μ΄μƒμ˜ ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€κ°€ μž…λ ₯되면 μ‹œκ°„ 초과둜 μ˜€λ‹΅ 처리λ₯Ό 내버린닀고 ν•œλ‹€.

πŸ’‘κ·Έλž˜μ„œ μ‹œκ°„ λ³΅μž‘λ„λ₯Ό 쀄이기 μœ„ν•΄ λ‹€λ₯Έ ν•΄κ²° 방법을 생각해보닀가 μ•½μˆ˜κ°€ μ•„λ‹Œ 수λ₯Ό μ—°μ‚°ν•˜μ§€ μ•ŠλŠ” 아이디어λ₯Ό μ•Œκ²Œ λ˜μ—ˆλ‹€. κ·ΈλŸ¬λ‹ˆκΉŒ N은 N의 μ•½μˆ˜μ˜ 배수둜 이루어져 있기 λ•Œλ¬Έμ— 이λ₯Ό μ΄μš©ν•˜μ—¬ DP 배열을 λ§Œλ“€ 수 μžˆλ‹€. 즉, 미리 DP 배열을 λ§Œλ“€μ–΄ 놓고 그에 λ§žλŠ” 값을 μž…λ ₯ λ°›μ•„ 좜λ ₯ν•˜λ©΄ λœλ‹€. 이 경우의 μ‹œκ°„λ³΅μž‘λ„λŠ” $O(nlogn)$이라고 ν•œλ‹€.

πŸ“–DP 배열을 μ΄μš©ν•œ ν•΄κ²° 방법

  1. 각 숫자의 μ•½μˆ˜μ˜ 합을 μ €μž₯ν•˜λŠ” λ¦¬μŠ€νŠΈμ™€ dp 리슀트의 λˆ„μ  합을 μ €μž₯ν•˜λŠ” 리슀트λ₯Ό μ„ μ–Έν•œλ‹€.
  2. 2λΆ€ν„° MAXκΉŒμ§€μ˜ μˆ˜μ— λŒ€ν•΄ λ°˜λ³΅λ¬Έμ„ μ‹€ν–‰ν•œλ‹€.
  3. 각 숫자 i에 λŒ€ν•΄ i의 λ°°μˆ˜λ“€μ„ μ°Ύμ•„κ°€λ©° dp 리슀트의 값을 μ—…λ°μ΄νŠΈν•œλ‹€.

예λ₯Ό λ“€μ–΄ iκ°€ 2일 경우 dp[2], dp[4], dp[6], ... 등을 i만큼 μ¦κ°€μ‹œν‚¨λ‹€.

  1. 1λΆ€ν„° MAXκΉŒμ§€μ˜ μˆ«μžμ— λŒ€ν•΄ s 리슀트λ₯Ό λˆ„μ ν•©μœΌλ‘œ κ³„μ‚°ν•œλ‹€.
  2. μž…λ ₯으둜 λ“€μ–΄μ˜€λŠ” iter 횟수만큼 λ°˜λ³΅λ¬Έμ„ μ‹€ν–‰ν•˜λ©΄μ„œ n 값을 μž…λ ₯λ°›λŠ”λ‹€.
  3. s[n] 값을 ans λ¦¬μŠ€νŠΈμ— μΆ”κ°€ν•œλ‹€.
  4. ans 리슀트의 값을 μ€„λ°”κΏˆμœΌλ‘œ κ΅¬λΆ„ν•˜μ—¬ 좜λ ₯ν•œλ‹€.

β¬‡οΈμ΅œμ’… μ½”λ“œ

MAX = 1000000
# 각 숫자의 μ•½μˆ˜μ˜ 합을 μ €μž₯ν•˜λŠ” 리슀트λ₯Ό μ„ μ–Έν•œλ‹€.
dp = [1] * (MAX + 1)
# dp 리슀트의 λˆ„μ  합을 μ €μž₯ν•˜λŠ” 리슀트λ₯Ό μ„ μ–Έν•œλ‹€.
s = [0] * (MAX + 1)
# 2λΆ€ν„° MAXκΉŒμ§€μ˜ μˆ˜μ— λŒ€ν•΄ λ°˜λ³΅λ¬Έμ„ μ‹€ν–‰ν•œλ‹€.
for i in range(2, MAX + 1):
    j = 1
    # 각 숫자 i에 λŒ€ν•΄ i의 λ°°μˆ˜λ“€μ„ μ°Ύμ•„κ°€λ©° dp 리슀트의 값을 μ—…λ°μ΄νŠΈν•œλ‹€.
    while i * j <= MAX:
        # 예λ₯Ό λ“€μ–΄ iκ°€ 2일 경우 dp[2], dp[4], dp[6], ... 등을 i만큼 μ¦κ°€μ‹œν‚¨λ‹€.
        dp[i * j] += i
        j+=1
# 1λΆ€ν„° MAXκΉŒμ§€μ˜ μˆ«μžμ— λŒ€ν•΄ s 리슀트λ₯Ό λˆ„μ ν•©μœΌλ‘œ κ³„μ‚°ν•œλ‹€.
for i in range(1, MAX + 1):
    s[i] = s[i-1] + dp[i]
iter = int(input())
ans = []
for k in range(iter):
    #μž…λ ₯으둜 λ“€μ–΄μ˜€λŠ” iter 횟수만큼 λ°˜λ³΅λ¬Έμ„ μ‹€ν–‰ν•˜λ©΄μ„œ n 값을 μž…λ ₯λ°›λŠ”λ‹€.
    n = int(input())
    # s[n] 값을 ans λ¦¬μŠ€νŠΈμ— μΆ”κ°€ν•œλ‹€.
    ans.append(s[n])
# ans 리슀트의 값을 μ€„λ°”κΏˆμœΌλ‘œ κ΅¬λΆ„ν•˜μ—¬ 좜λ ₯ν•œλ‹€.
print('\n'.join(map(str,ans)) + '\n')

image
⁉️근데 python으둜 ν•˜λ©΄ μ‹œκ°„ μ΄ˆκ³Όκ°€ 뜨고 pypy3둜 μ½”λ“œλ₯Ό μ œμΆœν•˜λ©΄ 톡과가 λ˜λŠ”λ° 뭐가 λ§žλŠ” κ±ΈκΉŒμš”...?

πŸ“š μƒˆλ‘­κ²Œ μ•Œκ²Œλœ λ‚΄μš©

μ°Έκ³ ν•œ μ‚¬μ΄νŠΈ
아직 DP κ°œλ…μ„ μ •ν™•ν•˜κ²Œ νŒŒμ•…ν•˜κ³  μžˆμ§€ λͺ»ν•˜κ³  있기 λ•Œλ¬Έμ— 이 λ¬Έμ œλŠ” DP κ°œλ…μ„ ν™•μ‹€νžˆ 작고 λ‹€μ‹œ ν•œλ²ˆ 풀어봐야겠닀...πŸ₯Ή

@Hwangyerin
Copy link
Collaborator

γ„·γ„±γ„·γ„±γ„·γ„±πŸ”₯

@LJEDD2
Copy link
Collaborator

LJEDD2 commented Mar 7, 2024

Python3 κ³Ό pypy3 의 차이λ₯Ό 잘 정리해주신 λΈ”λ‘œκ·Έκ°€ μžˆλ„€μš” !!
컴파일과 인터프리터 λ°©μ‹μ˜ 차이에 λŒ€ν•΄ 쑰금 더 μžμ„Ένžˆ μ•Œμ•„λ³Ό 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€ γ…Žγ…Ž

  • Python3의 μ‹€ν–‰μ‹œ μ‹œκ°„μ΄ 맀우 였래 κ±Έλ¦°λ‹€λŠ” 단점이 μžˆμ–΄, 그것을 κ°œμ„ ν•˜κ³ μž JIT 컴파일 방식을 λ„μž…ν•œ μ–Έμ–΄κ°€ PyPy3라고 ν•©λ‹ˆλ‹€.
  • ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•˜κΈ° 전에 컴파일 ν•˜λŠ” λŒ€μ‹ , ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•˜λŠ” μ‹œμ μ—μ„œ ν•„μš”ν•œ 뢀뢄듀을 μ¦‰μ„μœΌλ‘œ 컴파일 ν•˜λŠ” λ°©μ‹μž…λ‹ˆλ‹€.
  • 보톡 인터프리터 μ–Έμ–΄μ˜ μ„±λŠ₯ ν–₯상을 λͺ©μ μœΌλ‘œ λ„μž…ν•˜λŠ” κ²½μš°κ°€ λ§ŽμŠ΅λ‹ˆλ‹€.

πŸ’‘μ»΄νŒŒμΌ μ–Έμ–΄vs 인터프리터 μ–Έμ–΄
컴파일 μ–Έμ–΄ : μ†ŒμŠ€ μ½”λ“œλ₯Ό κΈ°κ³„μ–΄λ‘œ 컴파일(Compile time) -> μ‹€ν–‰ 파일 λ§Œλ“¦ -> μ‹€ν–‰(Run time)
인터프리터 μ–Έμ–΄ : μ½”λ“œλ₯Ό ν•œ 쀄씩 읽어 κ°€λ©° μ‹€ν–‰

μ—¬κΈ°μ„œ μˆ˜μ • 상황이 λ°œμƒν•˜λ©΄, μ†ŒμŠ€ 전체λ₯Ό λ‹€μ‹œ 컴파일 ν•  ν•„μš”κ°€ μ—†κ³ , μ½”λ“œ μˆ˜μ • ν›„ λ°”λ‘œ μ‹€ν–‰ κ°€λŠ₯ ν•œ 것이 인터프리터 μ–Έμ–΄μž…λ‹ˆλ‹€.
λ”°λΌμ„œ JIT(just in time) μ»΄νŒŒμΌμ€ μΈν„°ν”„λ¦¬νŠΈ κ³Όμ •μ—μ„œ 자주 μ“°μ΄λŠ” μ½”λ“œλ₯Ό μΊμ‹±ν•˜κΈ° λ•Œλ¬Έμ— μΈν„°ν”„λ¦¬ν„°μ˜ 느린 싀행속도λ₯Ό κ°œμ„ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
λ”°λΌμ„œ, PyPy3μ—μ„œλŠ” μ‹€ν–‰μ‹œ, 자주 μ“°μ΄λŠ” μ½”λ“œλ₯Ό μΊμ‹±ν•˜λŠ” κΈ°λŠ₯이 있기 λ•Œλ¬Έμ— λ©”λͺ¨λ¦¬λ₯Ό 쑰금 더 μ‚¬μš©ν•˜κ³  μ €μž₯ν•˜κ³  μžˆμ–΄, 싀행속도λ₯Ό κ°œμ„ ν•  수 μžˆλ‹€κ³  ν•©λ‹ˆλ‹€ !

κ°„λ‹¨ν•œ μ½”λ“œ : Python3κ°€ λ©”λͺ¨λ¦¬, 속도 μΈ‘μ—μ„œ μš°μ„Έ 
λ³΅μž‘ν•œ μ½”λ“œ : PyPy3κ°€ μš°μ„Έ

Copy link
Collaborator

@Hwangyerin Hwangyerin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 μ½”λ“œλ₯Ό 짜고 ν˜œμ›λ‹˜μ˜ μ½”λ“œμ™€ λΉ„κ΅ν•΄λ΄€λŠ”λ° 첫번째 μ‹œλ„μ™€ λΉ„μŠ·ν•˜λ„€μš₯..
dp.........곡뢀..저도. 곡뢀 ν•΄μ•Όν•  것 κ°™μŠ΅λ‹ˆλ‹€...
그리고 μ •μ€λ‹˜κ»˜μ„œ 달아주신 pythonκ³Ό pypy의 차이가 컴파일, 인터프리터 λ°©μ‹μ΄λΌλŠ” 것도 μ•Œκ²Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€.
21μ°¨μ‹œλ„ μˆ˜κ³ ν•˜μ…¨μŠ΅λ‹ˆλ‹€:)

Copy link
Member

@avocado-13 avocado-13 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 아직 dp κ°œλ…μ„ μ œλŒ€λ‘œ μ΅νžˆμ§€ λͺ»ν–ˆλŠ”데 μ°¨μΈ° 곡뢀λ₯Ό ν•΄λ΄μ•Όκ² μŠ΅λ‹ˆλ‹€ πŸ₯Ί
pypyκ°€ λ‹¨μˆœνžˆ 싀행속도가 λΉ λ₯΄λ‹€λŠ” κ²ƒλ§Œ μ•Œμ•˜λŠ”λ°, μ •μ€λ‹˜ 덕뢄에 인터프리터 언어와 컴파일 μ–Έμ–΄λ₯Ό μ œλŒ€λ‘œ κ΅¬λΆ„ν•˜κ³  κ°€λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€!

이번 μ°¨μ‹œ PR도 정말 수고 λ§ŽμœΌμ…¨μŠ΅λ‹ˆλ‹€ .πŸ‘πŸ»πŸ’šπŸ‘πŸ»πŸ’š

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants