• Pollard rho算法+Miller Rabin算法 BZOJ 3668 Rabin-Miller算法


    BZOJ 3667: Rabin-Miller算法

    Time Limit: 60 Sec  Memory Limit: 512 MB
    Submit: 1044  Solved: 322
    [Submit][Status][Discuss]

    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位长整形范围内。 

    分析:虽然题目叫做Miller rabin算法,不过真正上也需要Pollard rho算法

      1 /*貌似这个代码在BZOJ上的评测器就会运行错误,但是在POJ上一道原题却通过了(POJ上语言选C++可以过,选择G++就过不了)*/
      2 #include<iostream>
      3 using namespace std;
      4 #include<cstdio>
      5 #define S 10
      6 #include<cstdlib>
      7 #include<ctime>
      8 #define ll long long
      9 ll cas, maxz=-1;
     10 ll read()
     11 {
     12     ll ans=0;char c;
     13     c=getchar();
     14     while(c<'0'||c>'9') c=getchar();
     15     while(c>='0'&&c<='9') 
     16     {
     17         ans=ans*10+c-'0';
     18         c=getchar();
     19     }
     20     return ans;
     21 }
     22 ll quick_mul_mod(ll a,ll b,ll c)//a*b%c
     23 {
     24     ll ret=0;
     25     a%=c;b%=c;
     26     while(b)
     27     {
     28         if(b&1)
     29         {
     30             ret+=a;
     31             ret%=c;
     32             b--;
     33         }
     34         a<<=1;
     35         a%=c;
     36         b>>=1;
     37     }
     38     return ret;
     39 }
     40 ll gcd(ll a,ll b)
     41 {
     42     if(a==0) return 1;
     43     if(a<0) return gcd(-a,b);
     44     if(b==0)
     45     return a;
     46     return gcd(b,a%b);
     47 }
     48 ll Pollard_rho(ll x,ll c)
     49 {
     50     ll x1=rand()%(x-1)+1;
     51     ll x2=x1;
     52     int i=1,k=2;
     53     while(1)
     54     {
     55         i++;
     56         x1=(quick_mul_mod(x1,x1,x)+c)%x;
     57         ll d=gcd(x2-x1,x);
     58         if(d!=1&&d!=x) return d;
     59         if(x2==x1) return x;
     60         if(i==k)
     61         {
     62             x2=x1;
     63             k+=k;
     64         }
     65     }
     66     
     67 }
     68 ll quick_mod(ll a,ll b,ll c)//ji suan a^b%c
     69 {
     70     ll ans=1;
     71     a%=c;
     72     while(b)
     73     {
     74         if(b&1)
     75         {
     76             b--;
     77             ans=quick_mul_mod(ans,a,c);
     78         }
     79         b>>=1;
     80         a=quick_mul_mod(a,a,c);
     81     }
     82     return ans;
     83 }
     84 bool Miller_rabin(ll n)
     85 {
     86     if(n==2) return true;
     87     if(n<=1||!(n&1)) return false;
     88     ll u=n-1,t=0;
     89     while(!(u&1))
     90     {
     91         u>>=1;
     92         t++;
     93     }
     94     for(int i=0;i<S;++i)
     95     {
     96         ll x=rand()%(n-1)+1;
     97         x=quick_mod(x,u,n);
     98         for(int i=1;i<=t;++i)
     99         {
    100             ll y=quick_mul_mod(x,x,n);
    101             if(y==1&&x!=1&&x!=n-1)
    102               return false;
    103             x=y;
    104         }
    105         if(x!=1) return false;
    106     }
    107     return true;
    108 }
    109 void findpri(ll n)
    110 {
    111     if(n==1) return;
    112     if(Miller_rabin(n))
    113     {
    114         maxz=max(maxz,n);
    115         return;
    116     }
    117     ll p=n;
    118     while(p==n)
    119       p=Pollard_rho(p,rand()%(n-1)+1);
    120     findpri(p);
    121     findpri(n/p);
    122 }
    123 int main()
    124 {
    125     srand(time(0));
    126     cas=read();
    127     while(cas--)
    128     {
    129         maxz=0;
    130         ll n=read();
    131         findpri(n);
    132         if(maxz==n)/*最大的质因数就是本身*/
    133           printf("Prime
    ");
    134         else printf("%lld
    ",maxz);
    135     }
    136     return 0;
    137  } 
  • 相关阅读:
    向量、矩阵常用范数
    关于HP M451网络连接的资料
    pyqt程序最小化到系统托盘(未测试)
    博客园美化大集合2020最新!不用担心失效问题!
    添加QQ聊天
    关于加密
    python抓取谷歌学术关键词下文章题目
    如何确定网站可否可爬取
    灵狐浏览器
    利用beautifulsoup进行对标签的二次查找-以打印网易云歌单内容为例
  • 原文地址:https://www.cnblogs.com/c1299401227/p/5515229.html
Copyright © 2020-2023  润新知