백준/다시 볼만한 문제

[백준/BOJ] 11401 - 이항 계수 3 (c++) (페르마의 소정리, 분할정복)

sem; 2021. 3. 29. 12:29
반응형

1. 문제

www.acmicpc.net/problem/11401


2. 풀이

 

제일 오른쪽 수식에서의 분모가 0이 될 수 있는 가능성이 있기에 저렇게는 사용불가능하다.

 

여기서 페르마의 소정리가 쓰이는데

 

a^(p - 1) = 1 (mod p)는 합동식으로써 쉽게

 

a^(p - 1) mod p = 1 mod p과 같은 식이라고 생각하면 된다.

 

그래서

 

a^(p - 1) = 1 (mod p)

a * a^(p - 2) = 1 (mod p)

a^(p - 2) = a^-1 (mod p)이라고 볼 수 있다.

 

결론적으로

를 구하면되고 지수부분이 굉장히 크기 때문에

 

분할정복을 통해 제곱연산을 실행하면 시간내에 풀 수 있다.

 

분할정복을 통한 제곱연산 풀이:

zcacoding.tistory.com/2

 

백준 1629 - 곱셈 (c++) (분할정복)

1. 문제 www.acmicpc.net/problem/1629 2. 풀이 A의 B승은 A의 B/2승의 제곱과 같다. 위와 같이 지수가 짝수일 경우 단지 지수를 반으로 쪼개기만 하면 되었지만 아래의 수식과 같이 지수가 홀수일 경우 반으

zcacoding.tistory.com


 

3. 소스코드

#include <stdio.h>

typedef long long ll;

#define c 1000000007

int n, k;

ll power(ll n, ll m) {
	if (m == 0) return 1;
	ll tmp = power(n, m / 2);
	ll res = tmp * tmp % c;
	if (m % 2) return res * n % c;
	return res;
}

int main() {
	ll nfac = 1, kfac = 1;
	scanf("%d %d", &n, &k);
	for (int i = 1;i <= n;i++) {
		nfac *= i;
		nfac %= c;
	}
	for (int i = 1;i <= k;i++) {
		kfac *= i;
		kfac %= c;
	}
	for (int i = 1;i <= n - k;i++) {
		kfac *= i;
		kfac %= c;
	}
	kfac = power(kfac, c - 2);
	printf("%lld", nfac * kfac % c);
}

4. 참고

합동식

namu.wiki/w/%ED%95%A9%EB%8F%99%EC%8B%9D

 

합동식 - 나무위키

1. d∤bd\nmid bd∤b인데 해가 존재한다고 가정하자. 그럼 적당한 정수 yyy에 대하여 ax+my=bax+my=bax+my=b가 성립한다. 그런데 d∣ax+my=bd\mid ax+my=bd∣ax+my=b이므로 d∣bd\mid bd∣b이다. 이는 가정에 모순되므

namu.wiki

페르마의 소정리

namu.wiki/w/%ED%8E%98%EB%A5%B4%EB%A7%88%EC%9D%98%20%EC%86%8C%EC%A0%95%EB%A6%AC

 

페르마의 소정리 - 나무위키

먼저, 페르마의 소정리는 다음과 동치이다. ppp가 소수라면, np≡n(mod p) n^{p} \equiv n \left(\text{mod}\ p \right) np≡n(mod p) n=0n=0n=0일 경우는 자명하다. 이항정리에 의하면 (n+1)p=np+∑n=1p−1(pn)+1\displaystyle

namu.wiki


질문, 고칠점 등 댓글 언제나 환영입니다.

반응형