jisuanke: 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛B: Goldbach (米勒罗宾素数检验 OR JAVA 大数)
地址: https://nanti.jisuanke.com/t/25985
判断一个数是不是素数, 当数<1e7 时 我们可以用 素数筛法 ,开数组来判断,
但当素数很大时 超过 1e9 甚至为 1e18 , 就可以用米勒罗宾 来检验, 当超过1e18 的时候
请用 JAVA里的
BigInteger 里的 isProbablePrime(1) 函数吧.
一种方法是, 用米勒罗宾 判断
另一种 就是 Java了 在 [n/2-10000,n/2+10000] 里 寻找
[code]
#include<stdio.h> #include<bits/stdc++.h> using namespace std; typedef unsigned long long ll; inline ll mull(ll a,ll b,ll n) { ll ans=0; while(b) { if(b&1) ans=(ans+a)%n; a=(a+a)%n; b=b>>1; } return ans; } inline ll Pow_mod(ll a,ll b,ll n) { ll result=1; ll base=a%n; while(b) { if(b&1) result=mull(result,base,n)%n; base=mull(base,base,n)%n; b=b>>1; } return result; } bool judge(ll n) { if(n<=73) { int i; for(i=2; i*i<=n; i++) if(n%i==0) break; if(i*i>n) return 1; else return 0; } ll pan[4] = {2, 3, 7,11}; ll i; for(i=0; i<4; i++) if(Pow_mod(pan[i],n-1,n)!=1)break; if(i==4) return 1; else return 0; } int main() { int t; ll n; scanf("%d",&t); while (t--) { ll i=2; scanf("%llu",&n); while(1) { if (judge(i)&&judge(n-i)) { printf("%llu %llu\n",i,n-i); break; } i++; } } return 0; }
JAVA
import java.math.BigInteger; import java.util.Scanner; public class Main { static BigInteger zero= BigInteger.ZERO; static BigInteger one= BigInteger.ONE; public static void main(String[] args){ Scanner cin =new Scanner(System.in); int t; t=cin.nextInt(); // System.out.println(t); while(t--!=0) { BigInteger n; n=cin.nextBigInteger(); //System.out.println(n); BigInteger pn=n.divide(BigInteger.valueOf(2)); if( n.compareTo(BigInteger.valueOf(4))==0) { System.out.println(2+" "+2); continue; } for(BigInteger i= zero.max(pn.subtract(BigInteger.valueOf(10000)));i.compareTo(n.min(pn.add(BigInteger.valueOf(10000))))<0;i=i.add(BigInteger.valueOf(1))){ if(i.isProbablePrime(1) && n.subtract(i).isProbablePrime(1) ){ System.out.println(i+" "+(n.subtract(i))); break; } } } } }
参考文章:米勒-拉宾检验
12
岂曰无衣?与子同袍。王于兴师,修我戈矛。与子同仇!
岂曰无衣?与子同泽。王于兴师,修我矛戟。与子偕作!
岂曰无衣?与子同裳。王于兴师,修我甲兵。与子偕行!