zoukankan      html  css  js  c++  java
  • 素数小结

     素数基础: 1不是素数;除了2以外的所有偶数都是合数。
     1朴素判别素数
     判断一个数n是不是素数,只要判断从2到sqrt(n)的数是否能整除n,如果能则不是素数,否则就是素数。

     2朴素筛选法素数
     去掉当前素数的倍数(因为它们都是合数)

    private final static int VAL = 10000000;
        static int primeLen;
        static int[] primeArr = new int[VAL];
        static boolean[] isPrimeArr = new boolean[VAL];
    
        /**
      * 朴素筛法
      */
    public static void initPrimeArr() { Arrays.fill(isPrimeArr, false); isPrimeArr[1] = true; isPrimeArr[0] = true; for (int i = 2; i < VAL; i++) { if (!isPrimeArr[i]) { for (int j = i + i; j < VAL; j += i) { isPrimeArr[j] = true; } } } primeLen = 0; for (int i = 0; i < VAL; i++) { if (!isPrimeArr[i]) { primeArr[primeLen++] = i; } } }

     3线性筛法
     利用每个合数必有一个最小质因数,每个合数仅被它的最小素因数筛去正好一次。

        private final static int VAL = 10000000;
        static int primeLen;
        static int[] primeArr = new int[VAL];
        static boolean[] isPrimeArr = new boolean[VAL];
    
        /**
         * 线性筛选素数
         */
        public static void initPrimeArr() {
            Arrays.fill(isPrimeArr, false);
            primeLen = 0;
            for (int i = 2; i < VAL; i++) {
                if (!isPrimeArr[i]) {
                    primeArr[primeLen++] = i;
                }
                for (int j = 0; (j < primeLen) && (i * primeArr[j] < VAL); j++) {
                    isPrimeArr[i * primeArr[j]] = true;
                    if (i % primeArr[j] == 0) {
                        break;
                    }
                }
            }
        }

     先剔除除2以外的所有偶数,在根据剔除最小素因数的合数的方法,如下:

        private final static int VAL = 10000000;
        static int primeLen;
        static int[] primeArr = new int[VAL];
        static boolean[] isPrimeArr = new boolean[VAL];
    
        /**
         * 线性筛选素数
    */ public static void initPrimeArr() { Arrays.fill(isPrimeArr, false); primeLen = 0; primeArr[primeLen++] = 2; for (int i = 4; i < VAL; i += 2) { isPrimeArr[i] = true; } for (int i = 3; i < VAL; i += 2) { if (!isPrimeArr[i]) { primeArr[primeLen++] = i; } for (int j = 0; (j < primeLen) && (i * primeArr[j] < VAL); j++) { isPrimeArr[i * primeArr[j]] = true; if (i % primeArr[j] == 0) { break; } } } }

     4求区间素数

    static int intervalPrimeLen;
        static int[] intervalPrimeArr = new int[VAL];
        static boolean[] isIntervalPrimeArr = new boolean[VAL];
    
        public static void findIntervalPrimeArr(int L, int R) {
            int temp = (int) Math.sqrt(1.0 * R);
            int interval = R - L + 1;
            Arrays.fill(isIntervalPrimeArr, true);
            for (int i = 0, j; (i < primeLen) && (primeArr[i] <= temp); i++) {
                if ((j = L / primeArr[i] * primeArr[i]) < L) {
                    j += primeArr[i];
                }
                if (j < primeArr[i] * primeArr[i]) {
                    j = primeArr[i] * primeArr[i];
                }
                for (; j <= R; j += primeArr[i]) {
                    isIntervalPrimeArr[j - L] = false;
                }
            }
            intervalPrimeLen = 0;
            for (int i = 0; i < interval; i++) {
                if (isIntervalPrimeArr[i] && (i + L > 1)) {
                    intervalPrimeArr[intervalPrimeLen++] = i + L;
                }
            }
        }
    
        public static void findIntervalPrimeArr2(int L, int R) {
            int interval = R - L + 1;
            int temp = (int) Math.sqrt(1.0 * R);
            Arrays.fill(isIntervalPrimeArr, false);
            // 把偶数直接去掉,开始是L是否为奇偶数
            for (int i = (L & 1); i <= interval; i += 2) {
                isIntervalPrimeArr[i] = true;
            }
            for (int i = 3, j; i <= temp; i += 2) {
                if ((i > L) && isIntervalPrimeArr[i - L]) {
                    continue;
                }
                j = (L / i) * i;
                if (j < L) {
                    j += i;
                }
                if (j == i) {
                    j += i;
                }
                j -= L;
                for (; j < interval; j += i) {
                    isIntervalPrimeArr[j] = true;
                }
            }
            if (L <= 1) {
                isIntervalPrimeArr[1 - L] = true;
            }
            if (L <= 2) {
                isIntervalPrimeArr[2 - L] = false;
            }
            intervalPrimeLen = 0;
            for (int i = 0; i < interval; i++) {
                if (!isIntervalPrimeArr[i]) {
                    intervalPrimeArr[intervalPrimeLen++] = i + L;
                }
            }
        }


    5某个数的最小素因数

        static int intervalPrimeLen;
        static int[] intervalPrimeArr = new int[VAL];
        static int[] primeFactorArr = new int[VAL];
    
        public static void mkPrimeAndFactor() {
            Arrays.fill(primeFactorArr, 0);
            primeFactorArr[0] = 1;
            primeFactorArr[1] = 1;
            primeLen = 0;
            for (int i = 2; i < VAL; i++) {
                if (primeFactorArr[i] == 0) {
                    primeArr[primeLen++] = i;
                    primeFactorArr[i] = i;
                }
                for (int j = 0; (j < primeLen)
                        && (i * primeArr[j] < VAL)
                        && (primeArr[j] <= primeFactorArr[i] || primeFactorArr[i] == 0); j++) {
                    primeFactorArr[i * primeArr[j]] = primeArr[j];
                    if (i % primeArr[j] == 0) {
                        break;
                    }
                }
            }
        }

     6大素数判定

    米勒罗宾算法

    Java中的大数BigInteger中的isProbableprime(int certainty )

  • 相关阅读:
    ●BZOJ 3926 [Zjoi2015]诸神眷顾的幻想乡
    ●BZOJ 1396 识别子串
    ●UVA 1608 Non-boring sequences
    ●SPOJ 8222 NSUBSTR–Substrings
    ●SPOJ 7258 Lexicographical Substring Search
    ●CodeForces 429D Trick_Function
    ●BZOJ 2555 SubString
    ●洛谷P2664 树上游戏
    ●洛谷P3168 [CQOI2015]任务查询系统
    【UVA1057】Routing
  • 原文地址:https://www.cnblogs.com/xiaoxian1369/p/2697537.html
Copyright © 2011-2022 走看看