bzoj 3667: Rabin-Miller算法
Contents
3667: Rabin-Miller算法
Time Limit: 60 Sec Memory Limit: 512 MB
Description
Input
第一行:CAS,代表数据组数(不大于350),以下CAS行,每行一个数字,保证在64位长整形范围内,并且没有负数。你需要对于每个数字:第一,检验是否是质数,是质数就输出Prime
第二,如果不是质数,输出它最大的质因子是哪个。
Output
第一行CAS(CAS<=350,代表测试数据的组数)
以下CAS行:每行一个数字,保证是在64位长整形范围内的正数。
对于每组测试数据:输出Prime,代表它是质数,或者输出它最大的质因子,代表它是和数
Sample Input
6
2
13
134
8897
1234567654321
1000000000000
Sample Output
Prime
Prime
67
41
4649
5
HINT
数据范围:
保证cas<=350,保证所有数字均在64位长整形范围内。
Source
Rabin-Miller素数测试、Pollard-rho大因数分解 的模板题
附一个算法讲解,非常妙
http://www.cnblogs.com/Doggu/p/MillerRabin_PollardRho.html
orz 古大爷
#include<map> #include<cmath> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cstdlib> using namespace std; #define inf 1000000007 #define ll long long #define N 100010 inline ll rd() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } ll T,x,pri[10]={0,2,3,5,7,11,13}; ll mul(ll a,ll b,ll p) { ll tmp=a*b-(ll)((long double)a/p*b+1e-8)*p; if(tmp<0) tmp+=p;return tmp; } ll ksm(ll a,ll b,ll p) { ll sum=1; while(b) { if(b&1) sum=mul(sum,a,p); a=mul(a,a,p);b>>=1; } return sum; } bool MR(ll n) { if(n==2) return 1; if(n<2||!(n&1)) return 0; for(int i=1;i<=6;i++) { if(n==pri[i]) return 1; if(ksm(pri[i],n-1,n)!=1) return 0; } ll t,a,tp; for(int i=1;i<=6;i++) { t=n-1;a=pri[i]; while(!(t&1)) { tp=ksm(a,t>>1,n); if(tp==n-1) break;; if(tp^1) return 0; t>>=1; } } return 1; } ll mx; ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll f(ll x,ll n,ll c) { ll y=mul(x,x,n)+c; if(y>=n) y-=n; return y; } ll rho(ll n) { ll c=406,x,y,p; for(;;c++) { x=rand()%n; y=f(x,n,c); while(1) { p=gcd(abs(x-y),n); if(p^1) return p; x=f(x,n,c);y=f(f(y,n,c),n,c); if(x==y) break; } } } void sol(ll n) { if(n==1||n<mx) return ; if(MR(n)){mx=max(mx,n);return;} ll tp=rho(n); sol(tp);sol(n/tp); } int main() { srand(19740727); T=rd(); while(T--) { x=rd(); if(MR(x)){puts("Prime");continue;} mx=0;sol(x); printf("%lld\n",mx); } return 0; }
发表评论