3667: Rabin-Miller算法

来源:互联网 发布:解题王软件下载 编辑:程序博客网 时间:2024/06/06 00:17

题目链接

题目大意:检验大整数是否为质数,若不是输出其最大的质因子

题解:丢板子跑
题解

我的收获:这两个算法思想强啊

#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; #define abs(a) (a>0?a:-(a)) typedef long long ll; const ll a[]={2,3,5,7,11,13,17,19,23,29}; int cas;ll maxs;void read(ll &x){      char ch;      for(ch=getchar();!isdigit(ch);ch=getchar());      for(x=0;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; } ll gcd(ll a,ll b){return !b?a:gcd(b,a%b);} ll mul(ll a,ll b,ll p){     ll d=((long double)a/p*b+1e-8);     ll res=a*b-d*p;     res=res<0?res+p:res;     return res; } ll qpow(ll a,ll b,ll c){     ll res=1;     for (;b;b>>=1,a=mul(a,a,c))         if (b&1) res=mul(res,a,c);     return res; } bool check(ll a,ll n,ll r,ll s){     ll x=qpow(a,r,n),pre=x;//先算a^r次方     for (int i=1;i<=s;i++){//平方s次就是a^(n-1)         x=mul(x,x,n);         if(x==1&&pre!=1&&pre!=n-1) return 0;         pre=x;     }    return x==1;//费马小定理检测 } bool MR(ll n){     if(n<=1) return 0;     ll r=n-1,s=0;    while(!(r&1)) r>>=1,s++;//把n-1拆成2^s*r     for(int i=0;i<9;i++){         if(a[i]==n) return 1;//……         if(!check(a[i],n,r,s)) return 0;     }     return 1; } ll pol_rho(ll n,ll c){     ll k=2,x=rand()%n,y=x,p=1;     for(ll i=1;p==1;i++){         x=(mul(x,x,n)+c)%n;//f(x)=(x^2+c)%n         p=abs(x-y);        p=gcd(n,p);         if(i==k) y=x,k+=k;//floyd判圈     }     return p; } void solve(ll n){     if(n==1) return;     if(MR(n)){maxs=max(maxs,n);return;}     ll t=n;     while(t==n) t=pol_rho(n,rand()%(n-1));     solve(t),solve(n/t); } void init(){    srand(1564651598);     scanf("%d",&cas);     while(cas--){         ll x;maxs=0;         read(x),solve(x);         if(maxs==x) puts("Prime");         else printf("%lld\n",maxs);     } }int main(){     init();     return 0; } 
原创粉丝点击