zoukankan      html  css  js  c++  java
  • FZU 1649 Prime number or not米勒拉宾大素数判定方法。

    C - Prime number or not
    Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

    Description

    Your task is simple.Give you a number N, you should judge whether N is a prime number or not.

    Input

    There are multiple test cases. For each test case, there is an integer N(2<=N<=10^18).

    Output

    For each test case, you should output whether N is a prime number or not.If N is a prime number , you should output "It is a prime number."; otherwise you should output "It is not a prime number.";

    Sample Input

    2 4

    Sample Output

    It is a prime number. It is not a prime number.

    这里关键的问题在于数据达到了1亿亿,没办法用普通的方法进行运算,所以这里用到了米勒拉宾大素数判定方法。

    算法流程:根据费马小定理,a^(n-1)mod n==1,1<a<n,n为奇素数。随机在1~n的范围内取一个数a,进行式子的判定,返回1,就是伪素数,否则就是合数。因为伪素数是素数 的可能性为3/4,也就是正确率是1-1/4^k,所以我们要按定一个k使得正确率尽可能得大。所以要多次重复取随机数,然后判定。

    文字代码:

    1:重复MAX次运算

    2:在1~n中取得随机数a

    3:计算a^(n-1)mod n?=1,在这个计算里,注意到n可能很大,所以a^(n-1)可能越界,就想到用快速幂来边乘,边取模,但是又发现在n很大的时候,a*a都有可能溢出,所以想到了用快速幂的方法,进行快速积取模,边加边取模。这里的两个快速可避免溢出

    4:在3中可得到的数如果为1,则在循环未结束前继续从2开始操作,否则直接返回0,表示n是合数

    5:如果上面的循环能完整做完,说明n已经是强伪素数,我们可以返回1,判定为素数。

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<time.h>
     4 #define MAX 10
     5 __int64 muti(__int64 a,__int64 b,__int64 m)
     6 {
     7         __int64 ans=0;
     8         while(b)
     9         {
    10                 if(b&1)
    11                 ans=(ans+a)%m;
    12                 a=2*a%m;
    13                 b/=2;
    14         }
    15         return ans;
    16 }
    17 __int64 pow(__int64 a,__int64 b,__int64 m)
    18 {
    19         __int64 ans=1;
    20         while(b)
    21         {
    22                 if(b&1)
    23                 ans=muti(ans,a,m);
    24                 a=muti(a,a,m);//二进制。快速幂的思想 
    25                 b/=2;
    26         }
    27         return ans;
    28 }
    29 int miller_rabin(long long n)
    30 {
    31     __int64 i,a;
    32     if(n==2)
    33         return 1;
    34     if(n<2||!(n&1))
    35         return 0;
    36     srand((unsigned)time(NULL));
    37     for(i=1;i<=MAX;i++)
    38     {
    39         a=rand()%(n-2)+1;
    40         if(pow(a,n-1,n)!=1)
    41             return 0;
    42     }
    43     return 1;
    44 }
    45 int main()
    46 {
    47     __int64 n;
    48     while(scanf("%I64d",&n)!=EOF)
    49     if(miller_rabin(n))
    50     printf("It is a prime number.
    ");
    51     else printf("It is not a prime number.
    ");
    52     return 0;
    53 }
  • 相关阅读:
    扫描线算法模板
    spark submit 常用设置
    networkx 画有向图 使用DiGraph
    超实用的Spark数据倾斜解决
    解决spark中遇到的数据倾斜问题
    TrickBot 恶意木马软件
    windows 打开snappy文件 安装python snappy——还是直接用pip install xx.whl 打包好的安装吧
    解决CentOS删除文件后没有释放磁盘空间(lsof命令)
    Linux 系统下 centOS 7 ipconfig 提示没有安装
    tomcat启动报错org.apache.catalina.LifecycleException: The configured protocol [org.apache.coyote.http...
  • 原文地址:https://www.cnblogs.com/13224ACMer/p/4972817.html
Copyright © 2011-2022 走看看