삼성SW아카데미/[Professional]
5607. 조합
2744m
2020. 4. 4. 21:10
N combination R의 값을 1234567891로 나눈 나머지를 출력.
즉, 우리에게 익숙한 nCr을 1234567891로 나눈 나머지를 출력하란 말이다.
nCr을 구하는 공식을 보면
이다.
하지만 나머지 연산은 나눗셈에 적용할 수 없다.
그래서 이 식을 곱셈 형태로 바꿔줘야 하는데 여기서 사용되는 것이
페르마의 소정리이다.
페르마의 소정리에 의해서
P를 1234567891이라고 하면
가 성립한다.
제곱의 경우는 분할 정복을 통해서 O(logP)의 시간복잡도 안에 해결할 수 있기 때문에 해결이 가능하다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | import java.util.Scanner; public class Solution { static final int MOD = 1234567891; static long[] factorMOD; static int N, R; public static void main(String[] args) { // TODO Auto-generated method stub Scanner sc = new Scanner(System.in); int T = sc.nextInt(); for (int tc = 1; tc <= T; tc++) { N = sc.nextInt(); R = sc.nextInt(); factorMOD = new long[N + 1]; factorMOD[1] = 1; for (int i = 2; i <= N; i++) factorMOD[i] = factorMOD[i - 1] * i % MOD; // A = N! ^ MOD %MOD long A = power(factorMOD[N], MOD) % MOD; // B = (R!*(N-R)!)^MOD-2 % MOD long B = power(factorMOD[R], MOD - 2) * power(factorMOD[N - R], MOD - 2) % MOD; long res = A * B % MOD; System.out.println("#" + tc + " " + res); } } static long power(long N, long x) { if (x == 1) return N % MOD; else { if (x % 2 == 1) { long tmp = power(N, (x - 1) / 2); return tmp * tmp % MOD * N % MOD; } else { long tmp = power(N, x / 2); return tmp * tmp % MOD; } } } } | cs |