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

  • 相关阅读:
    asp.net 页面生命周期事件详细
    linux服务nfs与dhcp篇
    linux服务samba与ftp篇
    官网Android离线文档下载
    Android发布apk后解决百度地图不显示的问题
    win10和office2013激活
    Android-Intent and Intent Filters
    Android设置透明状态
    Android获取屏幕大小(Px)
    我的java web之路(JSP基本语法)
  • 原文地址:https://www.cnblogs.com/mhy12345/p/3833241.html
Copyright © 2011-2022 走看看