1. 문제
15712번: 등비수열
첫째 줄에 a, r, n, mod가 공백으로 구분되어 주어진다. a, r, n, mod는 모두 1보다 크거나 같고, 109보다 작거나 같은 자연수이다.
www.acmicpc.net
초항이 a, 공비가 r, 항 수가 n인 등비수열의 합을 mod로 나눈 나머지를 구하는 간단한 문제
초항이 a이고 공비가 r이며 항 수가 n인 등비수열의 합은.. 공비 r이 1이 아니면,
S=a×rn−1r−1
이라는 아주 쉬운 공식이 있고 이거에 따라 계산해서 mod로 나눈 나머지 구하면 되는거 아니냐
라고 쉽게 생각하면 이 문제는 풀수가 없다
a,r,n이 작으면 상관 없겠지만... 매우 크면 rn을 계산을 못한다
그러면 뭐 modular exponentiation으로 나머지로 거듭제곱하면 되는거 아니냐.. 하지만 r-1 나눗셈이 있어서..
잘 알겠지만 모듈로 연산에서 나눗셈은 일반적으로 성립하지 않는다
모듈로 연산의 역원을 구하면 되는거 아니냐.. 당연하지만 r과 mod가 서로소가 아니면 존재하지 않는다
2. 기하급수의 점화식
다음과 같은 기하급수 1+r+r2+r3+...+rn에 대해 생각해보자.
n = 0이면 1
n = 1이면 1+r
n = 2이면 1+r+r2
----------------------------------------------------------------------------------------------------------------------------------------
n = 3부터 홀수만 자세히 살펴보면..
1+r+r2+r3=1+r+(1+r)r2=(1+r)×(1+r2)
n = 5이면..
1+r+r2+r3+r4+r5=(1+r)×(1+r2+r4)
n = 7이면..
1+r+r2+r3+r4+r5+r6+r7=(1+r)×(1+r2+r4+r6)
규칙이 보이는가?
쉽게 생각해서.. 2개 항씩 묶어보면.. (1+r)이 공통인수로 있고, 각각은 1, r2, r4, r6,... 씩 곱한 값을 더하면 된다.
n = 2k+1로 홀수라면..
1+r+r2+r3+r4+r5+...+r2k+r2k+1=(1+r)×(1+r2+r4+...+r2k)
수학적 귀납법으로 모든 음이 아닌 정수 k=0,1,2,...에 대해 성립한다는 것은 쉽게 증명할 수 있다.
k=0에서는 위에서 n=1일때 1+r임을 보였고
n=2k+1에서 위 식이 성립한다고 하면... n=2k+3에서 보이면 된다.
n = 2k+3이면..
1+r+r2+r3+r4+r5+...+r2k+r2k+1+r2k+2+r2k+3
여기서.. r2k+2+r2k+3=(1+r)r2k+2이므로..
이걸 1+r로 묶으면 뭐..
(1+r)×(1+r2+r4+...+r2k+r2k+2)
----------------------------------------------------------------------------------------------------------------------------------------
이번엔 짝수에 대해서 알아보자.
n = 0이면 1
n = 2이면 1+r+r2
n = 4부터 자세히 살펴보면..
1+r+r2+r3+r4=1+r+r2+(r+r2)r2=1+(r+r2)(1+r2)
n = 6이면..
1+r+r2+r3+r4+r5+r6=1+r+r2+(r+r2)r2+(r+r2)r4)=1+(r+r2)(1+r2+r4)
n = 8 이면..
1+r+r2+r3+r4+r5+r6+r7+r8=1+(r+r2)(1+r2+r4+r6)
벌써 규칙이 보이는가??
n = 2k라면..
1+r+r2+r3+r4+...+r2k−1+r2k=1+(r+r2)(1+r2+r4+...+r2(k−1))
수학적 귀납법으로 역시 쉽게 증명 가능하다.
모든 자연수 k=1,2,...에 대하여..
k = 1이면.. 1+r+r2인 것은 자명하고
n=2k에서 성립한다고 가정하고, n=2k+2에서 성립함을 보인다.
1+r+r2+r3+r4+...+r2k−1+r2k+r2k+1+r2k+2에서..
r2k+1+r2k+2=(r+r2)r2k니까...
1+r+r2+r3+r4+...+r2k−1+r2k+r2k+1+r2k+2=1+(r+r2)(1+r2+r4+...+r2(k−1)+r2k)
------------------------------------------------------------------------------------------------------------------------------
3. 파이썬 구현 예시
알고리즘을 정리하면 다음과 같게 된다.
G(r,n)=1+r+r2+r3+...+rn을 구하려면...
3-1) n = 0이면 G(r,0)=1
3-2) n = 2k+1로 홀수라면..
1+r+r2+r3+r4+r5+...+r2k+r2k+1=(1+r)×(1+r2+r4+...+r2k)
여기서 1+r2+r4+...+r2k은 자세히 살펴보면.. r 대신에 r2을 넣은 기하급수와 마찬가지다.
1+r2+r4+...+r2k=1+(r2)1+(r2)2+...+(r2)k
k는 어떻게 구해??
아주 간단하다. n=2k+1이니까.. n-1 = 2k이고... 그러면 (n-1)/2 = k잖아
그래서... 1+r+r2+r3+r4+r5+...+r2k+r2k+1=(1+r)×(1+r2+r4+...+r2k)은 다음과 같이 바꿔 쓸 수 있다.
G(r,n)=(1+r)×G(r2,(n−1)/2)
3-3) n = 2k로 짝수라면..
1+r+r2+r3+r4+...+r2k−1+r2k=1+(r+r2)(1+r2+r4+...+r2(k−1))
마찬가지로..
1+r2+r4+...+r2(k−1)=1+(r2)1+(r2)2+...+(r2)k−1
이고... n = 2k이면.. k-1 = (n-2)/2니까..
1+r+r2+r3+r4+...+r2k−1+r2k=1+(r+r2)(1+r2+r4+...+r2(k−1))은 다음과 같이 바꿔쓸 수 있다.
G(r,n)=1+(r+r2)×G(r2,(n−2)/2)
이 결과를 재귀함수로 다음과 같이 나타낼 수 있을 것이다.
#기하급수의 합
#r은 공비, n은 마지막 항의 지수(항 수-1)
def geometric(r,n):
if n == 0:
return 1
else:
#n이 홀수
#g(r,n) = (1+r)g(r**2,(n-1)/2)
if n % 2 == 1:
return (1+r)*geometric(r*r, (n-1)//2)
#n이 짝수
#g(r,n) = 1+(r+r**2)g(r**2,(n-2)/2)
else:
return 1 + (r+r*r)*geometric(r*r, (n-2)//2)
하지만... 이렇게 구하면.. r과 n이 매우 클때 당연히 계산이 느려진다.
그러니까 이 값을 mod로 나눈 나머지를 요구하는 것이다.
#기하급수의 합
#r은 공비, n은 마지막 항의 지수(항 수-1), mod는 나머지 연산
def geometric(r,n,mod):
if n == 0:
return 1
else:
#n이 홀수
#g(r,n) = (1+r)g(r**2,(n-1)/2)
if n % 2 == 1:
return ((1+r)%mod*geometric(r*r%mod, (n-1)//2, mod))%mod
#n이 짝수
#g(r,n) = 1+(r+r**2)g(r**2,(n-2)/2)
else:
return 1 + ((r+r*r)%mod*geometric(r*r%mod, (n-2)//2,mod))%mod
4. 풀이
초항이 a, 공비가 r, 항 수가 n인 등비급수의 합은
a+ar+ar2+...+arn−1=a(1+r+r2+...+rn−1)이다.
위에서 구한 기하급수 점화식에 a를 곱하고, mod로 나눈 나머지를 구하면 되겠다.
from sys import stdin
def geometric(r,n,mod):
if n == 0:
return 1
else:
if n % 2 == 1:
return ((1+r)%mod*geometric(r*r%mod,(n-1)//2,mod))%mod
elif n % 2 == 0:
return 1+((r+r*r)%mod*geometric(r*r%mod,(n-2)//2,mod))%mod
a,r,n,mod = map(int,stdin.readline().split())
print((a%mod)*geometric(r,n-1,mod)%mod)
참조
algorithm - Geometric Series Modulus operation - Stack Overflow
Geometric Series Modulus operation
I am giving a series in the form of 1+r+r^2+r^3+r^4+r^5 I have to find modulus of a sum of series i.e i have to find this value [(r^n-1)/(r-1)]%M I can easily calculate the value of (r^n-1)%M ...
stackoverflow.com
'정수론' 카테고리의 다른 글
중국인의 나머지 정리(Chinese Remainder Theorem) 기본 이해하기 (0) | 2022.12.30 |
---|---|
약수의 합과 약수의 개수 공식 익히기 (0) | 2022.12.26 |
오일러의 정리를 배우고 거듭제곱의 나머지를 구하는 방법 익히기 (0) | 2022.12.18 |
모듈로 연산에서 나눗셈을 하는 방법(모듈로 곱셈의 역원 구하기) (0) | 2022.12.16 |
확장된 유클리드 알고리즘(extended euclidean algorithm) 구현해보면서 익히기 (0) | 2022.12.16 |