본문 바로가기

Notice
Recent Posts
Recent Comments
«   2024/05   »
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
Tags
더보기
Archives
관리 메뉴

15711. 환상의 짝꿍 본문

알고리즘 문제풀기/백준(Acmicpc)

15711. 환상의 짝꿍

알광(Algwang) 2019. 1. 30. 14:31

문제링크 : https://www.acmicpc.net/problem/15711


< 입력 >


테스트케이스 수(1<=T<=500)


2개의 끈의 길이 A,B (1<=A,B<=2*10^12)


< 출력 >


2개의 끈을 붙인 다음 정확히 2개의 소수로 나눌 수 있다면 YES, 아니면 NO


< 풀이 >


개인적으로 많은 이론을 안다고 자부할 수 있는 것도 아니고 문제를 보자마자 패턴을 떠올릴 자신이 없었다.


그래서 직접 A와 B의 합을 2부터 약 40까지 증가시키며 확인을 했다.


그렇게 진행하며 발견한 내용은 아래와 같다.


i) 4 이상의 짝수는 2개의 소수로 나눌 수 있다.


ii) 2를 제외한 모든 소수는 홀수이다.

   따라서 소수 + 2로 만들 수 없는 모든 홀수는 2개의 소수의 합으로 나눌 수 없다.


결국 4 이상의 짝수면 YES, 홀수면 -2한 값이 소수면 YES이고 나머지는 NO이다.


i)은 증명이 필요한 추측이지만 문제를 만드신 디디님의 블로그에서 이미 증명이 된 내용이라는 것을 알 수 있었다.


디디님 블로그 : https://blog.naver.com/rdd573/221270230610


이제 홀수에서 -2를 한 값이 소수인지 아닌지 구별만 하면 된다 !


근데 A와 B의 최대값이 2*10^12이다.


사실 진짜 문제는 이 부분이었다..


특정 수가 소수인지 O(logN)에 확인을 해야한다는 뜻이다.


그 부분에서 멘붕이 와서 방법을 찾아보던 중에 "밀러-라빈 소수판별법"이라는 방법을 발견했다.


내용을 정확하게 이해하지 못해서 설명은 https://casterian.net/archives/396 에서 보는걸로.. 헿


특정 수가 소수인지 O(logN)시간에 확인할 수 있는 방법이다.


이 방법은 확률론적 소수 판별법으로 "합성수이다."와 "아마도 소수일 것이다."라고 판별할 수 있다.


아마도라는 것은 예외가 있을 수 있다는 것이다.


하지만 2^32 이하의 경우 2,7,61 / 2^64 이하의 경우 2,325,9375,28178,450775,9780504,1795265022에


대해서만 밀러-라빈 소수판별법을 적용해봐도 예외가 발생하지 않게 된다.


정말 신기한 이론인데 이해하기 너무 어렵다.. 이해해봐야지 ㅜㅜ




- 소스 코드 -


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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import java.util.Scanner;
 
public class Main {
    static long primeTest[]= {2,325,9375,28178,450775,9780504,1795265022};
    public static void main(String[] args) {
        Scanner scan=new Scanner(System.in);
        int T=scan.nextInt();
        
        for(int test_case=1;test_case<=T;test_case++) {
            long A=scan.nextLong();
            long B=scan.nextLong();
            
            long sum=A+B;
            
            if(sum<4) {
                System.out.println("NO");
            }else if(sum%2==0) {
                System.out.println("YES");
            }else {
                sum-=2;
                if(is_prime(sum)) {System.out.println("YES");}
                else {System.out.println("NO");}
            }
        }
    }
    // calculate (x + y) % m; overflow-safe
    public static long addmod(long x, long y, long m) {
        x %= m;
        y %= m;
        return (x >= m - y? x - (m - y) : x + y);
    }
     
    // calculate (x * y) % m; overlow-safe
    public static long mulmod(long x, long y, long m) {
        x %= m;
        y %= m;
        long r = 0;
        while (y > 0) {
            if (y % 2 == 1)
                r = addmod(r, x, m);
            x = addmod(x, x, m);
            y /= 2;
        }
        return r;
    }
     
    // calculate x^y % m; overflow-safe
    public static long powmod(long x, long y, long m) {
        x %= m;
        long r = 1;
        while (y > 0) {
            if (y % 2 == 1)
                r = mulmod(r, x, m);
            x = mulmod(x, x, m);
            y /= 2;
        }
        return r;
    }
     
    // true for probable prime, false for composite
    public static boolean miller_rabin(long n, long a) {
        long d = n - 1;
        while (d % 2 == 0) {
            if (powmod(a, d, n) == n-1)
                return true;
            d /= 2;
        }
        long tmp = powmod(a, d, n);
        return tmp == n-1 || tmp == 1;
    }
     
    public static boolean is_prime(long n) {
        if (n <= 1)
            return false;
        if (n <= Long.parseLong("10000000000")) {
            for (long i = 2; i*<= n; i++)
                if (n % i == 0)
                    return false;
            return true;
        }
        for (long a : primeTest)
            if (!miller_rabin(n, a))
                return false;
        return true;
    }
}
 
cs





'알고리즘 문제풀기 > 백준(Acmicpc)' 카테고리의 다른 글

16986. 인싸들의 가위바위보  (0) 2019.03.02
1322. X와 K  (0) 2019.01.31
1124. 언더프라임  (0) 2019.01.29
2018. 수들의 합 5  (0) 2019.01.28
2004. 조합 0의 개수  (0) 2019.01.28
Comments