POJ-1811-프라임 테스트 (pollard_rho 템플릿, 신속하게 작은 소인수 찾기)

주제 포털

솔 : Pollard_Rho 템플릿 질문, 그냥 가지 Pollard_Rho 원칙을 많이 읽고 Miller_Rabin은 읽을 수 없습니다, 그러나 거의 결론이 코드를 노크 기억할 수 있습니다.

  • Pollard_Rho
    사용법 #include " cstdio " 
    사용법 #include " cstdlib " 
    사용법 #include " 알고리즘 " 
    사용법 #include " ctime이 " 
    사용  스페이스 성병; 
    타입 정의  LL; 
    LL의 GCD (LL A, LL의 b) { 
        복귀 ㄴ == 0 ? A : GCD (B, A의 % B); 
    } 
    LL의 muli_mod (LL의 N, LL의 K, P는 LL) { 
        LL의 m = 0 ;
        하면서 (K) {
             경우 (K & 1 ) m = (m + N) %의 P; = (N + N) %의 P; 
            K >> = 1 ; 
        } 
        리턴 m 단계; 
    } 
    LL의 pow_mod (LL의 N, LL의 K, P는 LL) { 
        LL에 m = 1 ;
        하면서 (K) {
             경우 (K & 1 ) m = muli_mod (m, N, P); 
            N = muli_mod (N, P); 
            K >> = 1 ; 
        } 
        리턴 m 단계; 
    } 
    LL의 miller_rabin (LL 않음) { 
        경우 (N 개의 == 2 ) 복귀  ;
        경우 (N < 2|| ! (n은 1 )) 반환  거짓 ; 
        LL의 m = N - 1 ; INT (S) = 0 ;
        반면 ((m &! 1 ))의 ++, m = >> 1 ;
        위한 ( int로 I = 1 ] = 1은 < 5 ; 내가 ++ ) { 
            LL의 R = 랜드 () % (N - 1 ) + 1 ; 
            LL의 Y = pow_mod (R, m, N);
             ( INT의 J = 1 ; J <가 S, J ++ ) { 
                LL의 X= muli_mod (Y, Y, N);
                경우 (엑스 == 1 && Y =! 1 && Y = N! - 1 ) 반환  거짓 ; 
                의 Y =의 X; 
            } 
            경우 (Y =! 1 ) 반환  거짓 ; 
        } 
        반환  사실 ; 
    } 
    LL의 pollard_rho (LL의 N, LL의 c) { 
        int로 I = 1 , K = 2 ; 
        LL X = 랜드 () (N - % 1 ) + 1 ; 
        LL Y =의 X;
        동안( ) { 
            X = (muli_mod (X, X, N) + c) %의 N; 
            LL 피 = GCD ((Y - X + N) %의 N, N);
            경우 (p> 1 && p <n)의 복귀 P;
            경우 (X == y)를 반환 N;
            경우 (I ++ == K) { 
                K << = 1 ; 
                의 Y =의 X; 
            } 
        } 
    } 
    (LL 않음) {ll 발견 
        되는 경우 (miller_rabin (N)) 복귀 N 단계; 
        LL 된 P = N;
        동안(p> = N) p = pollard_rho (N, P, 랜드 () % (- 1 ) + 1 );
        리턴 분 ((찾을) p (찾을 N / P)); 
    } 
    INT 의 main () {
         INT의 t; LL N;
    //     부터 srand (시간 (NULL)); 
        scanf와 ( " %의 D " , t);
        반면 (t-- ) { 
            는 scanf ( " %의 LLD " , N); 
            LL p를 = (N)을 발견;
            경우 (P는 == n)도 풋 ( " 프라임 " );
            다른 사람 의 printf ( " % LLD \ 없음" , P); 
        } 
        리턴  0 ; 
    }

    POJ 사용을하지 __gcd에서 보편적 머리, 알고리즘을 사용하지. 그것의 핵심부터 srand는 매우 구덩이를 RE.

추천

출처www.cnblogs.com/Angel-Demon/p/11593930.html