본문으로 건너뛰기
김신건의 로그

수학 (Mathematics)

· 수정 · 📖 약 5분 · 1,459자/단어 #algorithm #foundation #math
math, 수학, 정수론 기초, modular arithmetic

정의

수학 (Mathematics) 은 문제 해결에 필요한 모듈러 산술 (modular arithmetic), 최대공약수/최소공배수 (GCD/LCM), 거듭제곱 (exponentiation), 합 공식 (sum formulas) 등 정수론과 대수학 기초를 포괄하는 PS 태그. solved.ac 에서 가장 많은 문제를 포함하는 범용 태그.

역사적으로 유클리드 호제법 (Euclidean Algorithm, BC 300년경), 페르마의 소정리 (Fermat’s Little Theorem, 1640), 오일러 정리 (Euler’s Theorem, 1763) 등이 현대 PS 의 모듈러 연산 / 역원 계산에 직접 쓰인다.

문제 상황과 동기

PS 에서 수학 태그는 다음 세 범주로 나뉜다.

  1. 모듈러 산술: 답을 10^9 + 7 로 나눈 나머지로 요구. long long 범위 초과 방지.
  2. GCD/LCM: 두 수의 공약수 / 공배수 관계. naive 반복문은 O(max(a, b)), 유클리드는 O(log min(a, b)).
  3. 거듭제곱: a^N mod M 을 빠르게. naive O(N) vs 분할정복 O(log N).
  4. 합 공식 / 조합: 1+2+...+N, 이항계수 C(N, K), 등. 직접 반복 vs 공식.

핵심 통찰: 나머지 연산의 distributive property분할정복 이 log 복잡도를 만든다.

실무 / PS 위치: 암호학 (RSA), 해시 (rolling hash), DP 최적화, 조합론 전처리.

시각화

핵심 아이디어

모듈러 산술

(a + b) mod M = ((a mod M) + (b mod M)) mod M
(a - b) mod M = ((a mod M) - (b mod M) + M) mod M
(a · b) mod M = ((a mod M) · (b mod M)) mod M

주의: 나눗셈은 역원 필요. a / b mod M = a · b^(-1) mod M, 여기서 b^(-1)b · b^(-1) ≡ 1 (mod M) 인 값. M 이 소수면 페르마의 소정리로 b^(-1) = b^(M-2) mod M.

유클리드 호제법 (GCD)

gcd(a, b) = gcd(b, a mod b)   if b ≠ 0
gcd(a, 0) = a

a mod b 가 매번 절반 이하로 줄어들어 O(log min(a, b)).

lcm(a, b) = a · b / gcd(a, b) (오버플로우 조심, a / gcd(a, b) · b 순서로).

분할정복 거듭제곱

pow(a, N, M):
    if N == 0: return 1
    half = pow(a, N/2, M)
    result = (half · half) mod M
    if N is odd: result = (result · a) mod M
    return result

O(log N). a^10 = (a^5)^2 = ((a^2 · a)^2)^2 같은 식으로.

합 공식

  • 1 + 2 + ... + N = N(N+1)/2
  • 1^2 + 2^2 + ... + N^2 = N(N+1)(2N+1)/6
  • 등차수열 합 S = n(a + l)/2 (첫항 a, 끝항 l, 항 개수 n)

알고리즘

GCD (유클리드 호제법)

gcd(a, b):
    while b ≠ 0:
        (a, b) = (b, a mod b)
    return a

분할정복 거듭제곱

fast_pow(a, N, M):
    result = 1
    a = a mod M
    while N > 0:
        if N is odd:
            result = (result · a) mod M
        a = (a · a) mod M
        N = N / 2
    return result

모듈러 역원 (M 이 소수)

mod_inv(a, M):   # M prime
    return fast_pow(a, M - 2, M)

구현

// GCD, 거듭제곱, 모듈러 역원
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD = 1e9 + 7;

ll gcd(ll a, ll b) {
  while (b) { ll tmp = a % b; a = b; b = tmp; }
  return a;
}

ll fast_pow(ll a, ll N, ll M) {
  ll res = 1; a %= M;
  while (N > 0) {
      if (N & 1) res = res * a % M;
      a = a * a % M;
      N >>= 1;
  }
  return res;
}

ll mod_inv(ll a, ll M) { return fast_pow(a, M - 2, M); }

int main() {
  ll a, b, N;
  cin >> a >> b >> N;
  cout << "gcd(" << a << ", " << b << ") = " << gcd(a, b) << "\n";
  cout << "lcm(" << a << ", " << b << ") = " << a / gcd(a, b) * b << "\n";
  cout << a << "^" << N << " mod " << MOD << " = " << fast_pow(a, N, MOD) << "\n";
  cout << "inverse of " << a << " mod " << MOD << " = " << mod_inv(a, MOD) << "\n";
  ll inv_a = mod_inv(a, MOD);
  cout << "verify: " << a << " * " << inv_a << " mod " << MOD << " = " << (a * inv_a % MOD) << "\n";
}
stdin
12 18 1000000000
결과
gcd(12, 18) = 6
lcm(12, 18) = 36
12^1000000000 mod 1000000007 = 469271275
inverse of 12 mod 1000000007 = 083333334
verify: 12 * 083333334 mod 1000000007 = 1

복잡도

항목
GCD (유클리드)O(log min(a, b))
분할정복 거듭제곱O(log N) 시간, O(1) 공간 (꼬리재귀 최적화)
모듈러 역원O(log M) (거듭제곱 한 번)
naive 거듭제곱O(N) - 절대 쓰면 안 됨 (N=10^9 → TLE)

변형 / 활용

기법설명복잡도
확장 유클리드ax + by = gcd(a, b) 의 정수해 (x, y)O(log min(a, b))
페르마의 소정리M 소수일 때 a^(M-1) ≡ 1 (mod M)-
오일러 정리M 과 a 서로소일 때 a^φ(M) ≡ 1 (mod M)-
이항계수 mod MC(N, K) mod M 을 Lucas / 전처리 팩토리얼 역원O(M) 전처리 + O(1) 쿼리
중국인의 나머지 정리x ≡ a1 (mod M1), x ≡ a2 (mod M2) 해 존재 조건O(log M)

함정

1. 모듈러 뺄셈 음수

(a - b) mod M 가 음수일 수 있다. C++/Java 에서 % M 결과가 음수면 + M 필요.

ll sub_mod(ll a, ll b, ll M) {
    return ((a - b) % M + M) % M;
}

2. LCM 오버플로우

lcm(a, b) = a * b / gcd(a, b) 순서로 하면 a * b 가 long long 범위 초과 가능. a / gcd(a, b) * b 로 먼저 나누기.

3. 0의 역원 / 0으로 나누기

mod_inv(0, M) 은 정의되지 않음. 문제에서 나누는 값이 0이 아님을 보장해야.

4. M이 합성수일 때 역원

M 이 소수가 아니면 페르마 안 됨. 확장 유클리드로 gcd(a, M) == 1 확인 후 역원 계산.

5. 거듭제곱 지수가 0

pow(a, 0, M) = 1 (a=0 이어도). 0^0 은 수학적으로 논란이지만 PS 에서는 보통 1.

BOJ 연습 문제

번호제목정답률링크
BOJ 1037약수45.2%kokoa-lab
BOJ 1934최소공배수60.8%kokoa-lab
BOJ 2609최대공약수와 최소공배수72.1%kokoa-lab
BOJ 6064카잉 달력36.4%kokoa-lab
BOJ 11401이항 계수 334.5%kokoa-lab
BOJ 13172Σ33.8%kokoa-lab
BOJ 17425약수의 합29.7%kokoa-lab
BOJ 1016제곱 ㄴㄴ 수24.1%kokoa-lab

참고

이 글의 용어 (4개)
모듈러 역원 (Modular Multiplicative Inverse)algorithm
정의 정수 a 의 모듈러 역원 (modular multiplicative inverse) 은 을 만족하는 정수 x. 기호로 또는 . 존재 조건: gcd(a, m) = 1 일 때만…
정수론 (Number Theory)algorithm
정의 정수론 (Number Theory) 은 정수의 성질과 관계를 연구하는 분야. PS 에서는 약수/배수, 소수 (prime), 모듈러 연산, 유클리드 호제법, 확장 유클리드, …
조합론 (Combinatorics)algorithm
정의 조합론 (Combinatorics) 은 유한 집합의 원소를 세는 수학 분야. PS 에서는 주로 순열 (Permutation), 조합 (Combination), 이항계수 (B…
중국인의 나머지 정리 (Chinese Remainder Theorem)algorithm
정의 중국인의 나머지 정리 (CRT) 는 다음과 같은 연립 합동식의 해가 유일 하게 존재함을 보장: 단, m1, m2, ..., mk 는 쌍마다 서로소 (pairwise copr…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기