zoukankan      html  css  js  c++  java
  • POJ 1811Prime Test(米勒拉宾素数测试)

    直接套用模板,以后接着用

    这里还有一个素因子分解的模板

      1 #include <map>
      2 #include <set>
      3 #include <stack>
      4 #include <queue>
      5 #include <cmath>
      6 #include <ctime>
      7 #include <vector>
      8 #include <cstdio>
      9 #include <cctype>
     10 #include <cstring>
     11 #include <cstdlib>
     12 #include <iostream>
     13 //#include <algorithm>
     14 using namespace std;
     15 #define INF 0x3f3f3f3f
     16 #define inf ((LL)1<<40)
     17 #define lson k<<1, L, mid
     18 #define rson k<<1|1, mid+1, R
     19 #define mem0(a) memset(a,0,sizeof(a))
     20 #define mem1(a) memset(a,-1,sizeof(a))
     21 #define mem(a, b) memset(a, b, sizeof(a))
     22 #define FOPENIN(IN) freopen(IN, "r", stdin)
     23 #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
     24 template<class T> T ABS ( T a) { return a >= 0 ? a : -a;   }
     25 template<class T> T CMP_MIN ( T a, T b ) { return a < b;   }
     26 template<class T> T CMP_MAX ( T a, T b ) { return a > b;   }
     27 template<class T> T MAX ( T a, T b ) { return a > b ? a : b; }
     28 template<class T> T MIN ( T a, T b ) { return a < b ? a : b; }
     29 template<class T> T GCD ( T a, T b ) { return b ? GCD ( b, a % b ) : a; }
     30 template<class T> T LCM ( T a, T b ) { return a / GCD ( a, b ) * b;     }
     31 template<class T> void SWAP( T& a, T& b ) { T t = a; a = b;  b = t;     }
     32 
     33 typedef __int64 LL;
     34 //typedef long long LL;
     35 const int MAXN = 10005;
     36 const int MAXM = 110000;
     37 const double eps = 1e-14;
     38 const double PI = 4.0 * atan(1.0);
     39 
     40 
     41 
     42 
     43 LL n, ans;
     44 int t;
     45 
     46 
     47 
     48 
     49 #define Times 10
     50 
     51 //产生[0, n-1]的一个随机数
     52 LL random(LL n)
     53 {
     54     return ((double)rand() / RAND_MAX * n + 0.5);
     55 }
     56 //乘法,采用加法模拟,避免中间结果超出LL
     57 LL multi(LL a,LL b,LL mod)
     58 {
     59     LL ans=0;
     60     while(b)
     61     {
     62         if(b & 1)
     63         {
     64             b--;
     65             ans=(ans+a) % mod;
     66         }
     67         else
     68         {
     69             b/=2;
     70             a=(2*a) % mod;
     71         }
     72     }
     73     return ans;
     74 }
     75 
     76 //快速幂,同样避免超出LL的做法
     77 LL Pow(LL a, LL b, LL mod)
     78 {
     79     LL ans=1;
     80     while(b)
     81     {
     82         if(b&1)
     83         {
     84             b--;
     85             ans=multi(ans,a,mod);
     86         }
     87         else
     88         {
     89             b/=2;
     90             a=multi(a,a,mod);
     91         }
     92     }
     93     return ans;
     94 }
     95 
     96 //miller_rabin的一遍探测,返回false表示是合数
     97 bool witness(LL a,LL n)
     98 {
     99     LL d=n-1;
    100     while( !(d&1) )
    101         d >>= 1;
    102     LL t=Pow(a, d, n);
    103     while(d!=n-1 && t!=1 && t!=n-1)
    104     {
    105         t=multi(t,t,n);
    106         d<<=1;
    107     }
    108     return t==n-1 || d&1;
    109 }
    110 
    111 //miller_rabin算法,返回false表示是合数,否则是素数
    112 //返回素数出错的概率(最高)为 1 / (4 ^ times)
    113 bool miller_rabin(LL n)
    114 {
    115     if(n == 2)
    116         return true;
    117     if( n<2 || !(n&1) )
    118         return false;
    119     for(int i = 1; i <= Times ; i++ )
    120     {
    121         LL a = random(n-2) + 1;
    122         if( !witness(a, n) )
    123             return false;
    124     }
    125     return true;
    126 }
    127 
    128 
    129 //************************************************
    130 //pollard_rho 算法进行质因数分解
    131 //************************************************
    132 LL factor[100];//质因数分解结果(刚返回时是无序的)
    133 int tol;//质因数的个数。数组小标从0开始
    134 
    135 LL gcd(LL a,LL b)
    136 {
    137     if(a==0)return 1;//???????
    138     if(a<0) return gcd(-a,b);
    139     while(b)
    140     {
    141         LL t=a%b;
    142         a=b;
    143         b=t;
    144     }
    145     return a;
    146 }
    147 
    148 LL Pollard_rho(LL x, LL c)
    149 {
    150     LL i=1,k=2;
    151     LL x0=rand()%x;
    152     LL y=x0;
    153     while(1)
    154     {
    155         i++;
    156         x0=(multi(x0, x0, x) + c) % x;
    157         LL d=gcd(y-x0,x);
    158         if(d!=1&&d!=x) return d;
    159         if(y==x0) return x;
    160         if(i==k){y=x0;k+=k;}
    161     }
    162 }
    163 
    164 //对n进行素因子分解
    165 void findfac(LL n)
    166 {
    167     if(miller_rabin(n))//素数
    168     {
    169         factor[tol++]=n;
    170         ans = MIN(ans, n);
    171         return;
    172     }
    173     LL p=n;
    174     while(p>=n)
    175         p=Pollard_rho(p, rand()%(n-1)+1);
    176     findfac(p);
    177     findfac(n/p);
    178 }
    179 
    180 
    181 
    182 int main()
    183 {
    184     //FOPENIN("in.txt");
    185     while(~scanf("%d", &t))while(t--)
    186     {
    187         ans = inf;
    188         scanf("%I64d", &n);
    189         findfac(n);
    190         if(miller_rabin(n))
    191             printf("Prime
    ");
    192         else printf("%I64d
    ", ans);
    193     }
    194     return 0;
    195 }
  • 相关阅读:
    this指针是什么?
    C++多态实现原理
    面试题2:实现Singleton模式
    面试题1:赋值运算符函数
    1.Two Sum
    朴素贝叶斯
    K近邻法
    感知机
    数据类型、用户交互、赋值运算
    蓝牙技术概述
  • 原文地址:https://www.cnblogs.com/gj-Acit/p/3926004.html
Copyright © 2011-2022 走看看