• poj 1181(大数判素数 ,分解)


      1 //miller_rabin 判断一个大数是否是素数
      2 //pollard_rho 大数因子分解
      3 #include<cstdio>
      4 #include<cstdlib>
      5 #include<cstring>
      6 #include<cmath>
      7 #include<algorithm>
      8 
      9 using namespace std;
     10 
     11 #define LL long long
     12 const LL Max = (LL) 1 << 62;
     13 LL p[10]={2,3,5,7,11,13,17,19,23,29};
     14 
     15 //计算a*b%n
     16 inline LL multi_mod(LL a,LL b,LL mod)
     17 {
     18     LL sum=0;
     19     while(b)
     20     {
     21         if(b&1)    sum = (sum + a) % mod;
     22         a <<= 1;
     23         b >>= 1;
     24         if (a >= mod) a %= mod;
     25     }
     26     return sum;
     27 }
     28 
     29 //计算a^b%n;
     30 inline LL quick_mod(LL a,LL b,LL mod)
     31 {
     32     LL sum = 1;
     33     while(b)
     34     {
     35         if(b & 1) sum = multi_mod(sum, a, mod);
     36         a = multi_mod(a, a, mod);
     37         b >>= 1;
     38     }
     39     return sum;
     40 }
     41 
     42 bool miller_rabin(LL n)
     43 {
     44     LL u,m,buf;
     45     int k = 0;
     46     //将n分解为m*2^k
     47     if(n==2)   return true;
     48     if(n<2 || !(n&1))    return false;
     49     m = n - 1;
     50     while(!(m&1))
     51         k++,m >>= 1;
     52     for(int i = 0; i < 9; ++i)
     53     {
     54         if(p[i] >= n) return true;
     55         u = quick_mod(p[i], m, n);
     56         if(u==1) continue;
     57         for(int j = 0; j < k; ++j)
     58         {
     59             buf = multi_mod(u, u, n);
     60             if(buf == 1 && u != 1 && u != n - 1)
     61                 return false;
     62             u = buf;
     63         }
     64         //如果p[i]^(n-1)%n!=1那么n为合数
     65         if(u - 1) return false;
     66     }
     67     return true;
     68 }
     69 
     70 LL gcd(LL a, LL b)
     71 {
     72     return b == 0 ? a: gcd(b, a%b);
     73 }
     74 //寻找n的一个因子,该因子并不一定是最小的,所以下面要二分查找最小的那个因子
     75 LL pollard(LL n )
     76 {
     77    LL x,y,c=0,d,i=1,k=2;
     78    while(c==0 || c==2 ) c = abs( rand())%(n-1) + 1;
     79    x = y = (rand( )%( n-1 )) + 1;
     80    do
     81    {
     82       i++;
     83       d = gcd( y + n - x, n );
     84       if( d >1 && d < n )
     85           return d; 
     86       if( i == k )
     87       {
     88          y = x; k <<= 1;        
     89       }    
     90       x = (multi_mod( x , x, n )+n-c )%n;
     91     }while( x != y );
     92     return n; 
     93 }
     94 
     95 LL pollard_min(LL n)
     96 {
     97     LL p,a,b=Max;
     98     if(n==1)    return Max;
     99     if(miller_rabin(n))    return n;
    100     p = pollard(n);
    101     a = pollard_min(p);//二分查找
    102     b = pollard_min(n / p);
    103     return a < b ? a : b;
    104 }
    105 
    106 int main(void)
    107 {
    108     LL T;
    109     LL n;
    110     scanf("%lld",&T);
    111     while(T--)
    112     {
    113         scanf("%lld",&n);
    114         if(miller_rabin(n))
    115         {
    116             puts("Prime");
    117         }
    118         else printf("%lld\n",pollard_min(n));
    119     }
    120     return 0;
    121 }
  • 相关阅读:
    市场规模的估算
    C#中的线程(一)入门 转载
    2.设计模式-Abstract Factory 抽象工厂模式
    1.设计模式
    Microsoft.Jet.OLEDB.4.0读取EXCEL数据
    转载--加盐密码哈希:如何正确使用
    ragel学习资源整合
    开源库xlslib跨平台编译
    WPF开源框架以及经典博客
    (转载)值得推荐的C/C++框架和库 (真的很强大)
  • 原文地址:https://www.cnblogs.com/Missa/p/3103898.html
Copyright © 2020-2023  润新知