大素数测试+求最小素因子+最大素因子(模版)

引用:http://blog.csdn.net/wsniyufang/article/details/6623576

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define MAXN 10
#define C 16381
using namespace std;
typedef __int64 I64;

I64 min;

I64 multi(I64 a, I64 b, I64 n){
    I64 tmp = a % n, s = 0;
    while(b){
        if(b & 1) s = (s + tmp) % n;
        tmp = (tmp + tmp) % n;
        b >>= 1;
    }
    return s;
}

I64 Pow(I64 a, I64 b, I64 n){
    I64 tmp = a % n, s = 1;
    while(b){
        if(b & 1) s = multi(s, tmp, n);
        tmp = multi(tmp, tmp, n);
        b >>= 1;
    }
    return s;
}

int witness(I64 a, I64 n){
    I64 u = n - 1, t = 0, i, x, y;
    while(!(u & 1))    u >>= 1, t ++;
    x = Pow(a, u, n);
    for(i = 1; i <= t; i ++){
        y = multi(x, x, n);
        if(y == 1 && x != 1 && x != n -1) return 1;
        x = y;
    }
    if(x != 1) return 1;
    return 0;
}

int test(I64 n){
    I64 a;
    int i;
    if(n == 2) return 1;
    if(n < 2 || !(n & 1)) return 0;
    srand((I64)time(0));
    for(i = 0; i < MAXN; i ++){
        a = ((I64) rand()) % (n - 2) + 2;
        if(witness(a, n)) return 0;
    }
    return 1;
}

I64 gcd(I64 a, I64 b){
    return b ? gcd(b, a % b) : a;
}

I64 pollard_rho(I64 n, I64 c){
    I64 x, y, d, i = 1, k = 2;
    srand((I64)time(0));
    x = ((I64) rand()) % (n - 1) + 1;
    y = x;
    while(1){
        i ++;
        x = (multi(x, x, n) + c) % n;
        d = gcd(y - x + n, n);
        if(d != 1 && d != n) return d;
        if(y == x) return n;
        if(i == k) y = x, k <<= 1;
    }
}

void find(I64 n, I64 c){
    I64 r;
    if(n <= 1) return;
    if(test(n)){
        if(min > n) min = n;
        return;
    }
    r = pollard_rho(n, c--);
    find(n / r, c);
    find(r, c);
}

I64 MaxPrimeFactor(I64 n)
{
    if(test(n))
    return n;
    
    I64 k=-1,g;
    min=n;
    find(n,C);
    
    g=MaxPrimeFactor(min);
    k=g>k?g:k;
    
    g=MaxPrimeFactor(n/min);
    k=g>k?g:k;
    return k;
}
int main(){
    I64 n;
        while(~scanf("%I64d", &n))
        {
            // if(test(n)){                //test(n)测试n是不是素数
            // printf("Prime\n");
            // continue;
            // }
            // min = n;                   //min表示n的最小素因子
            // find(n, C);                //找出n的最小素因子
            // printf("%I64d\n",min);
            printf("%I64d\n",MaxPrimeFactor(n));//求n的最大素因子
        }
    return 0;
}

 

posted on 2013-07-02 01:15  laymond  阅读(393)  评论(0编辑  收藏  举报

导航