• 大素数判断和素因子分解(miller-rabin,Pollard_rho算法)


      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stdlib.h>
      4 #include<time.h>
      5 #include<iostream>
      6 #include<algorithm>
      7 using namespace std;
      8 
      9 
     10 //****************************************************************
     11 // Miller_Rabin 算法进行素数测试
     12 //速度快,而且可以判断 <2^63的数
     13 //****************************************************************
     14 const int S=20;//随机算法判定次数,S越大,判错概率越小
     15 
     16 
     17 //计算 (a*b)%c.   a,b都是long long的数,直接相乘可能溢出的
     18 //  a,b,c <2^63
     19 long long mult_mod(long long a,long long b,long long c)
     20 {
     21     a%=c;
     22     b%=c;
     23     long long ret=0;
     24     while(b)
     25     {
     26         if(b&1){ret+=a;ret%=c;}
     27         a<<=1;
     28         if(a>=c)a%=c;
     29         b>>=1;
     30     }
     31     return ret;
     32 }
     33 
     34 
     35 
     36 //计算  x^n %c
     37 long long pow_mod(long long x,long long n,long long mod)//x^n%c
     38 {
     39     if(n==1)return x%mod;
     40     x%=mod;
     41     long long tmp=x;
     42     long long ret=1;
     43     while(n)
     44     {
     45         if(n&1) ret=mult_mod(ret,tmp,mod);
     46         tmp=mult_mod(tmp,tmp,mod);
     47         n>>=1;
     48     }
     49     return ret;
     50 }
     51 
     52 
     53 
     54 
     55 
     56 //以a为基,n-1=x*2^t      a^(n-1)=1(mod n)  验证n是不是合数
     57 //一定是合数返回true,不一定返回false
     58 bool check(long long a,long long n,long long x,long long t)
     59 {
     60     long long ret=pow_mod(a,x,n);
     61     long long last=ret;
     62     for(int i=1;i<=t;i++)
     63     {
     64         ret=mult_mod(ret,ret,n);
     65         if(ret==1&&last!=1&&last!=n-1) return true;//合数
     66         last=ret;
     67     }
     68     if(ret!=1) return true;
     69     return false;
     70 }
     71 
     72 // Miller_Rabin()算法素数判定
     73 //是素数返回true.(可能是伪素数,但概率极小)
     74 //合数返回false;
     75 
     76 bool Miller_Rabin(long long n)
     77 {
     78     if(n<2)return false;
     79     if(n==2)return true;
     80     if((n&1)==0) return false;//偶数
     81     long long x=n-1;
     82     long long t=0;
     83     while((x&1)==0){x>>=1;t++;}
     84     for(int i=0;i<S;i++)
     85     {
     86         long long a=rand()%(n-1)+1;//rand()需要stdlib.h头文件
     87         if(check(a,n,x,t))
     88             return false;//合数
     89     }
     90     return true;
     91 }
     92 
     93 
     94 //************************************************
     95 //pollard_rho 算法进行质因数分解
     96 //************************************************
     97 long long factor[100];//质因数分解结果(刚返回时是无序的)
     98 int tol;//质因数的个数。数组小标从0开始
     99 
    100 long long gcd(long long a,long long b)
    101 {
    102     if(a==0)return 1;//???????
    103     if(a<0) return gcd(-a,b);
    104     while(b)
    105     {
    106         long long t=a%b;
    107         a=b;
    108         b=t;
    109     }
    110     return a;
    111 }
    112 
    113 long long Pollard_rho(long long x,long long c)
    114 {
    115     long long i=1,k=2;
    116     long long x0=rand()%x;
    117     long long y=x0;
    118     while(1)
    119     {
    120         i++;
    121         x0=(mult_mod(x0,x0,x)+c)%x;
    122         long long d=gcd(y-x0,x);
    123         if(d!=1&&d!=x) return d;
    124         if(y==x0) return x;
    125         if(i==k){y=x0;k+=k;}
    126     }
    127 }
    128 //对n进行素因子分解
    129 void findfac(long long n)
    130 {
    131     if(Miller_Rabin(n))//素数
    132     {
    133         factor[tol++]=n;
    134         return;
    135     }
    136     long long p=n;
    137     while(p>=n)p=Pollard_rho(p,rand()%(n-1)+1);
    138     findfac(p);
    139     findfac(n/p);
    140 }
    141 
    142 int main()
    143 {
    144     //srand(time(NULL));//需要time.h头文件//POJ上G++不能加这句话
    145     long long n;
    146     while(scanf("%I64d",&n)!=EOF)
    147     {
    148         tol=0;
    149         findfac(n);
    150         for(int i=0;i<tol;i++)printf("%I64d ",factor[i]);
    151         printf("
    ");
    152         if(Miller_Rabin(n))printf("Yes
    ");
    153         else printf("No
    ");
    154     }
    155     return 0;
    156 }
  • 相关阅读:
    PHP0002:PHP基础1
    NodeJS_0001:关于install的方式
    JN_0018:运行窗口不显示
    事务、事务操作、事务隔离级别
    MySQL 常见的两种存储引擎
    8:二叉树的下一个节点
    链表
    文件压缩
    MapReduce--Shuffle原理
    volatile关键字
  • 原文地址:https://www.cnblogs.com/by-1075324834/p/5338976.html
Copyright © 2020-2023  润新知