计蒜客 25985.Goldbach-米勒拉宾素数判定(大素数) (2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 B)
若干年之前的一道题,当时能写出来还是超级开心的,虽然是个板子题。一直忘记写博客,备忘一下。
米勒拉判大素数,关于米勒拉宾是个什么东西,传送门了解一下:biubiubiu~
B. Goldbach
自己看题意吧,直接贴代码了。
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<cstdlib> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #include<stack> 10 using namespace std; 11 typedef unsigned long long ll; 12 const int maxn=1e9+10; 13 const double eps=1e-7; 14 ll add_mod(ll a,ll b,ll mod) //快乘法 基于快速幂的二分思想 15 { 16 ll ans=0; //由于考虑到取模数很大 快速幂会溢出 17 while(b) //必须使用该方法 18 { 19 if(b&1) //我这里写的是非递归版 20 ans=(ans+a)%mod; 21 a=a*2%mod; 22 b>>=1; 23 } 24 return ans; 25 } 26 27 ll pow_mod(ll a,ll n,ll mod) //快速幂 递归版 28 { 29 if(n>1) 30 { 31 ll tmp=pow_mod(a,n>>1,mod)%mod; 32 tmp=add_mod(tmp,tmp,mod); 33 if(n&1) tmp=add_mod(tmp,a,mod); 34 return tmp; 35 } 36 return a; 37 } 38 39 bool Miller_Rabbin(ll n,ll a) //米勒拉宾素数判断函数主体 40 { 41 ll d=n-1,s=0,i; 42 while(!(d&1)) // 先把(2^s)*d 算出来 43 { 44 d>>=1; 45 s++; 46 } 47 ll t=pow_mod(a,d,n); //a^d取一次余判断 48 if(t==1 || t==-1) //一或负一则可以声明这可能是质数 49 return 1; 50 for(i=0; i<s; i++) //不是的话继续乘上s个2 51 { 52 if(t==n-1) //(n-1)*(n-1)%n=1 这一步是优化 53 return 1; 54 t=add_mod(t,t,n); // 快乘 55 } 56 return 0; 57 } 58 59 int is_prime(ll n) 60 { 61 ll i,tab[4]= {3,4,7,11}; //本来应该取[1,n]内任意整数 62 for(i=0; i<4; i++) //但一般这几个数足以,不需要太多组测试 63 { 64 if(n==tab[i]) 65 return 1; //小判断小优化~ 66 if(!n%tab[i]) 67 return 0; 68 if(n>tab[i] && !Miller_Rabbin(n,tab[i])) 69 return 0; 70 } 71 return 1; 72 } 73 ll max(ll a,ll b) 74 { 75 return a>b?a:b; 76 } 77 int main() 78 { 79 int t; 80 scanf("%d",&t); 81 while(t--) 82 { 83 ll n; 84 scanf("%llu",&n); 85 if(n==4) 86 printf("2 2\n"); 87 else 88 { 89 for(ll i=2; i<=n/2; ++i) 90 { 91 if(is_prime(i)&&is_prime(n-i)) 92 { 93 printf("%llu %llu\n",i,n-i); 94 break; 95 } 96 } 97 } 98 } 99 }
当时还是我队友帮我D的bug,他现在都不理我了((ಥ_ಥ))
难受