zoukankan      html  css  js  c++  java
  • 大素数测试+求最小素因子+最大素因子(模版)

    引用: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
    ");
                // continue;
                // }
                // min = n;                   //min表示n的最小素因子
                // find(n, C);                //找出n的最小素因子
                // printf("%I64d
    ",min);
                printf("%I64d
    ",MaxPrimeFactor(n));//求n的最大素因子
            }
        return 0;
    }
  • 相关阅读:
    POJ 1611 The Suspects
    POJ 2001 Shortest Prefixes(字典树)
    HDU 1251 统计难题(字典树 裸题 链表做法)
    G++ C++之区别
    PAT 乙级 1013. 数素数 (20)
    PAT 乙级 1012. 数字分类 (20)
    PAT 乙级 1009. 说反话 (20)
    PAT 乙级 1008. 数组元素循环右移问题 (20)
    HDU 6063 17多校3 RXD and math(暴力打表题)
    HDU 6066 17多校3 RXD's date(超水题)
  • 原文地址:https://www.cnblogs.com/laymond/p/3166142.html
Copyright © 2011-2022 走看看