ç´ æ°å¤å® (Primality Test)
競ããçãªãã¨ãä¹ ãã¶ãã«ããã®ã§ãhttp://kanetai.hatenablog.com/entry/20110519/1305833341ã®ä¸é¨ãå°ãæ´çã
term | description |
---|---|
ç´æ°(divisor), å æ°,å å(factor) | ããèªç¶æ°ãå²ãåãæ´æ°ã |
ç´ æ°(prime number) | èªåèªèº«ã¨ï¼ä»¥å¤ã®èªç¶æ°ã§å²ãåããªã(æ£ã®ç´æ°ãã¡ããã©ï¼ã¤æã¤)èªç¶æ°ã |
åææ°(composite number) | ç´ æ°ã§ãªã2以ä¸ã®èªç¶æ°(ç´ æ°ã®ç©ã§è¡¨ããã¨ãã§ããèªç¶æ°)ã |
ç´ å æ°(prime factor) | ããèªç¶æ°ã®ç´æ°ã«ãªãç´ æ°ã |
ç´ æ´ãªå¤å®æ³
\(n\)ãç´ æ°ãã©ããå¤å®ããã«ã¯ã\([2, n)\)ã®ç¯å²ã®æ´æ°ã\(n\)ã®ç´æ°ãã©ããã確ãããã°ããããããã§\(n\)ãç´æ°\(d\)ãæã¤(åææ°)ã¨ããã¨ã
\(\frac{n}{d}\)ã\(n\)ã®ç´æ°\(\left( n=d \cdot \frac{n}{d}\right) \)ãªã®ã§ã
\(d \leq \sqrt{n} \lor \frac{n}{d} \leq \sqrt{n}\).ã(â» \( d \gt \sqrt{n} \land \frac{n}{d} \gt \sqrt{n} \) ã ã¨\(d \cdot \frac{n}{d} \gt n\)ã¨ãªã£ã¦ãã¾ã)
\[ n\text{ãåææ°}\rightarrow \sqrt{n}\text{ããå°ããç´ å æ°ãæã¤} \]
ã¤ã¾ã, \([2,\sqrt{n}]\)ã®ç¯å²ã®æ´æ°ã\(n\)ã®ç´æ°ã(\(n\)ãå²ãåããã)ã©ããã確ãããã°ãã. \(n\)ãå²ãåãããªããã®æ´æ°ã¯ç´ æ°ã§ã¯ãªã.è¨ç®éã¯\(O(\sqrt{n})\).
public static final boolean isPrime(int n){ if( n <= 1 ) return false; for(int i=2; i*i <= n;i++ ) if( n % i == 0 ) return false; return true; }
ã¨ã©ãã¹ããã¹ã®ç¯©(the sieve of Eratosthenes, Eratosthenes' sieve)
ä½åãç´ æ°å¤å®ãããããªããã°ãªããªãã¨ããä¸ã®ç´ æ°å¤å®ã§ã¯éå¹çãªã®ã§ã2以ä¸N以ä¸ã®ç´ æ°ãåæãããã¨ãèããã
- ã¾ãã2以ä¸N以ä¸ã®æ´æ°ãåæããã
- ãã®ä¸ã®æå°ã®æ°2ã¯ç´ æ°ã
- ç´ æ°ã®åæ°ã¯ç´ æ°ã§ã¯ãªãã®ã§ã2ã®åæ°ãåãé¤ãã
- 次ã«ãæ®ã£ãæå°ã®æ°ã¯ããã以ä¸ã®æ°ã§å²ãåããªãâãã®æ°ã¯ç´ æ°ã
- ç´ æ°ã®åæ°ãé¤ãã
\[\vdots\]
\([0,n]\)ã®ç´ æ°å¤å®ãã¼ãã«ãæ±ããå ´åãä¸ã§è¿°ã¹ãããã«\(i\)ã\([2, \sqrt{n} ]\)ã®ç¯å²ã§åãã°è¯ãã\(i\)ãç´ æ°ã®æããã®åæ°ã®ãã©ã°ãæããã\(2i, 3i, \cdots (i-1)iã\)ã«ã¤ãã¦ã¯æ¢ã«ãããã¦ããã¯ããªã®ã§ã\( [ i^2, n ] \)ã®ç¯å²ã§\(i\)ã®åæ°ã®ãã©ã°ãæãã°ãããâ»â©ã¯\([0,n)\)ã®ãã¼ãã«
è¨ç®éã¯\( O\left(n\log \log n \right) \)ç¨åº¦.
/** * Creates primality test table via Eratosthenes' sieve. <br> * O( nlog(log n) )<br> * @param n table_size * @return primality test table {isPrime(0), isPrime(1),..., isPrime(n-1)} */ public static final boolean[] sieve(int n){ boolean[] ret = new boolean[n]; Arrays.fill(ret, true); ret[0] = ret[1] = false; for(int i = 2; i*i < n; ++i) if(ret[i]) for(int j = i*i; j < n; j+=i) ret[j] = false; return ret; }
åºé篩(Segmented Sieve)
\(\sqrt{U}\)以ä¸ã®ç´ æ°ã使ã£ã¦ã¨ã©ãã¹ããã¹ã®ç¯©ããããã¨ã«ãã£ã¦ã \([L,U)\)ã®åºéã®ç´ æ°ãå¾ãã\(\sqrt{U}\)以ä¸ã®ç´ æ°ã¯ã¨ã©ãã¹ããã¹ã®ç¯©ãªã©ã使ã£ã¦æ±ãã¦ããã°è¯ãã\(\pi (x)\)ã\(x\)以ä¸ã®ç´ æ°ã®æ°ã¨ããã¨ãè¨ç®éã¯\( O ( (U-L)\pi (\sqrt{U}) ) \)ãç´ æ°å®çã«ããã¨ã\(\pi (x)\)ã¯\(\frac{x}{\log x}\)ç¨åº¦ãªã®ã§ã\(O((U-L)\frac{\sqrt{U}}{\log U})\)ã«ãªãã
â©ã¯\(\sqrt{U}\)以ä¸ã®ç´ æ°primeã渡ãã¦ã[L,U)ã®ç¯å²ã§ãtable[i] != 0 ãªã i+L ã¯ç´ æ°(i+L == table[i])ãªãã¼ãã«ãä½ã£ã¦ãããç´ æ°ã ã欲ããå ´åã¯, 0ã®è¦ç´ ãé¤ãã°è¯ãã空éè¨ç®éã¯\(O(\frac{\sqrt{U}}{\log U} + U-L)\)ã§ãããã(\(\sqrt{U}\)以ä¸ã®ç´ æ°ãå«ãã¦). \(L\)ã®å°ãåãããã©ã°ãæãå¿ è¦ãããã®ã§æ³¨æãå®è£ ã¯Spaghetti Sourceãåèã«ãã¦ã¾ããã»ã¨ãã©ãã®ã¾ã¾
public static final ArrayList<Integer> segmentedSieve(int L, int U, ArrayList<Integer> prime, boolean removeNonPrime) { if (!(0 <= L && L < U)) throw new IllegalArgumentException(); ArrayList<Integer> ret = new ArrayList<>(U-L); IntStream.range(L, U).forEach(i -> ret.add(i - L, i)); for(int p : prime) { if (p*p >= U) break; int j = (p >= L ? p*p : L % p == 0 ? L : L - (L % p) + p); for (; j < U; j += p) ret.set(j - L, 0); } return removeNonPrime ? ret.stream().filter(e -> e > 0).collect(Collectors.toCollection(ArrayList::new)) : ret; }
é次篩(Iterative Sieve)
é次çã«åºé篩ããè¡ããã¨ã«ãã£ã¦ãnã¾ã§ã®ç´ æ°ã空éè¨ç®éãæãã¦æ±ãããã¨ãã§ããã\(O(\frac{n}{\log n} + \sqrt{n})\)ç¨åº¦ã§æ±ãããããã競æããã°ã©ãã³ã°ã ã¨bitsetã«ããã¨ã©ãã¹ããã¹ã®ç¯©ã§ååãªã®ããç¥ããªãã
â©[0,n)ã«ã¤ãã¦ãé·ã\(\sqrt{n}\)ã®åºéãã¨ã«é次åºé篩ãããããsegmentedSieve()ã§åºéåã®ãã¼ãã«ãnewãã¦ãããæ¯ååã大ãããªã®ã§ãå®éã«ã¯ãã®åã®ãããã¡ãç¨æãã¦ä½¿ãã¾ãããæ¹ãç¡é§ãªnewãããªãã¦è¯ãããå¯èªæ§ãåªå ãã¦ããæ¸ãã¦ããªãã
public static final ArrayList<Integer> iterativeSieve(int n) { if (n <= 0) throw new IllegalArgumentException(); final int BLOCK = (int)Math.ceil(Math.sqrt(n)); ArrayList<Integer> ret = primeNumbers(BLOCK); //BLOCK以ä¸ã®ç´ æ° for (int b = BLOCK; b < n; b += BLOCK) { ArrayList<Integer> tmp = segmentedSieve(b , b+BLOCK, ret, false); ret.addAll(tmp.stream().filter(e -> 0 < e && e < n) //n以ä¸ã®ç´ æ°ãå ¥ã£ã¦ãã¾ã£ã¦ãè¯ãå ´åã¯0<eã ãã§è¯ãã .collect(Collectors.toList())); } return ret; }
åè
- spaghetti source
- wiki:ç´ æ°å®ç
- ã¨ã©ãã¹ããã¹ã®ãµããã¨ãã®è¨ç®é
- ç´ æ°åæã«ã¤ãã¦
TODO: 確çç´ æ°å¤å®ã¨ã