zoukankan      html  css  js  c++  java
  • hdu 2012 素数判定 Miller_Rabbin

    素数判定

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 71785    Accepted Submission(s): 24969


    Problem Description
    对于表达式n^2+n+41,当n在(x,y)范围内取整数值时(包括x,y)(-39<=x<y<=50),判定该表达式的值是否都为素数。
     
    Input
    输入数据有多组,每组占一行,由两个整数x,y组成,当x=0,y=0时,表示输入结束,该行不做处理。
     
    Output
    对于每个给定范围内的取值,如果表达式的值都为素数,则输出"OK",否则请输出“Sorry”,每组输出占一行。
     
    Sample Input
    0 1 0 0
     
    Sample Output
    OK
     
    Author
    lcy
     
    Source
     
    Recommend
    JGShining   |   We have carefully selected several similar problems for you:  2010 2014 2013 2011 2007 
     
    虽然说用筛数发加线段树是肯定能A的,但是还是试了一下Miller-Rabbin算法。
     
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    /*
    米勒-拉宾素数判定:
    1.求出s和R 使得N-1 = 2^s * R
    2.选出[1,N-1]的整数a (最好是质数)
    3.检验(a^d) mod N != 1且r从0到(s-1): (a^(2^r*s)) mod N != -1则N是合数
    4.如果不是合数有 75%概率是质数
    */
    int pow_mod(int x,int y,int mod)
    {
            int ret=1;
            while (y)
            {
                    if (y&1)ret=ret*x%mod;
                    x=x*x%mod;
                    y>>=1;
            }
            return ret;
    }
    bool Miller_Rabbin(int n,int a)//a属于[2,n-1]
    {
            if (n<2)return false;
            if (!(n%a))
                    return false;
            int r=0,s=n-1;
            while (!(s&1))
            {
                    s>>=1;
                    r++;
            }
            //将n-1分解为2^r * s   s为奇数 
            int k=pow_mod(a,s,n);
            if (k==1)return true;
            //如果a^s%n==1 为伪素数
            for (int i=0;i<r;i++)
            {
                    if (k==n-1)return true;
                    //对于任意 a^(s*2^i)%n==n-1 为伪素数 i属于[1,r-1]
                    k=k*k%n;
            }
            return false;
    }
    int main()
    {
            freopen("input.txt","r",stdin);
            int x,y,n,t;
            while (scanf("%d%d",&x,&y),x!=0||y!=0)
            {
                    int i;
                    bool flag=true;
                    for (i=x;i<=y;i++)
                    {
                            t=30;
                            while (t--)
                            {
                                    n=i*i+i+41;
                                    if (!Miller_Rabbin(n,rand()%(n-2)+2))
                                    {
                                            flag=false;
                                            break;
                                    }
                            }
                            if (!flag)break;
                    }
                    if (flag)
                    {
                            printf("OK
    ");
                    }else
                    {
                            printf("Sorry
    ");
                    }
            }
    }
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    jvm基本结构和解析
    多态的意思
    java中对象的简单解读
    double类型和int类型的区别
    python 解析xml文件
    win10不能映射Ubuntu共享文件
    Qt程序打包
    Ubuntu boot分区文件误删,系统无法启动,怎么解
    ubuntu Boot空间不够问题“The volume boot has only 5.1MB disk space remaining”
    Ubuntu 分辨率更改 xrandr Failed to get size of gamma for output default
  • 原文地址:https://www.cnblogs.com/mhy12345/p/3833241.html
Copyright © 2011-2022 走看看