zoukankan      html  css  js  c++  java
  • poj 1811 Prim test

    基本上一个裸的Miller_Rabin大素数判定和一个裸的Pollard_rho素数分解算法,当模板用吧!

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<stdlib.h>
      4 #define LL long long
      5 using namespace std;
      6 const int s=20;
      7 int tol;
      8 LL factor[100];
      9 
     10 LL mult_mod(LL a,LL b,LL c)//计算a*b%c;
     11 {
     12     LL ret=0;
     13     a%=c;
     14     b%=c;
     15     while(b>0)
     16     {
     17         if(b&1) ret=(ret+a)%c;
     18         a<<=1;
     19         if(a>=c) a%=c;
     20         b>>=1;
     21     }
     22     return ret;
     23 }
     24 
     25 LL pow_mod(LL a,LL b,LL mod)//计算a^b%b
     26 {
     27     if(b==1) return a%mod;
     28     a%=mod;
     29     LL tmp=a;
     30     LL ret=1;
     31     while(b>0)
     32     {
     33         if(b&1) ret=mult_mod(ret,tmp,mod);
     34         tmp=mult_mod(tmp,tmp,mod);
     35         b>>=1;
     36     }
     37     return ret;
     38 }
     39 
     40 //以a为基,n-1=x*2^t      a^(n-1)=1(mod n)  验证n是不是合数
     41 //一定是合数返回true,不一定返回false
     42 bool check(LL a,LL n,LL x,LL t)
     43 {
     44     LL ret=pow_mod(a,x,n);
     45     LL last=ret;
     46     for(int i=1; i<=t; i++)
     47     {
     48         ret=mult_mod(ret,ret,n);
     49         if(ret==1&&last!=1&&last!=n-1) return 1;
     50         last=ret;
     51     }
     52     if(ret!=1) return 1;
     53     return false;
     54 }
     55 
     56 // Miller_Rabin()算法素数判定
     57 //是素数返回true.(可能是伪素数,但概率极小)
     58 //合数返回false;
     59 bool Miller_Rabin(LL a)
     60 {
     61     if(a<2) return 0;
     62     if(a==2) return 1;
     63     if((a&1==0)) return 0;
     64     LL x=a-1;
     65     LL t=0;
     66     while((x&1)==0)
     67     {
     68         x>>=1;
     69         t++;
     70     }
     71     for(int i=0; i<s; i++)
     72     {
     73         long long b=rand()%(a-1)+1;
     74         if(check(b,a,x,t))
     75             return 0;
     76     }
     77     return 1;
     78 }
     79 
     80 LL gcd(LL a,LL b)
     81 {
     82     if(a==0)return 1;
     83     if(a<0) return gcd(-a,b);
     84     while(b)
     85     {
     86         LL t=a%b;
     87         a=b;
     88         b=t;
     89     }
     90     return a;
     91 }
     92 
     93 LL Pollard_rho(LL x,LL c)
     94 {
     95     LL i=1,k=2;
     96     LL x0=rand()%x;
     97     LL y=x0;
     98     while(1)
     99     {
    100         i++;
    101         x0=(mult_mod(x0,x0,x)+c)%x;
    102         LL d=gcd(y-x0,x);
    103         if(d!=1&&d!=x) return d;
    104         if(y==x0) return x;
    105         if(i==k)
    106         {
    107             y=x0;
    108             k+=k;
    109         }
    110     }
    111 }
    112 
    113 void findfac(LL n)
    114 {
    115     if(Miller_Rabin(n))//素数
    116     {
    117         factor[tol++]=n;
    118         return;
    119     }
    120     LL p=n;
    121     while(p>=n)p=Pollard_rho(p,rand()%(n-1)+1);
    122     findfac(p);
    123     findfac(n/p);
    124 }
    125 
    126 int main()
    127 {
    128     LL a;
    129     int n;
    130     scanf("%d",&n);
    131     while(n--)
    132     {
    133         scanf("%lld",&a);
    134         if(Miller_Rabin(a))
    135         {
    136             puts("Prime");
    137             continue;
    138         }
    139         tol=0;
    140         findfac(a);
    141         LL ans=factor[0];
    142         for(int i=1;i<tol;i++)
    143           if(factor[i]<ans)
    144              ans=factor[i];
    145         printf("%lld
    ",ans);
    146     }
    147     return 0;
    148 }
    View Code
  • 相关阅读:
    Android Button四种点击事件和长按事件
    Android 简单登陆 涉及 Button CheckBox TextView EditText简单应用
    Android EditText属性
    Android-TextView 控件常用属性以及基本用法
    对象数组空指针异常
    数字反转问题
    遇3问题
    队列解密QQ号
    线程先后执行问题
    小哼买书
  • 原文地址:https://www.cnblogs.com/yours1103/p/3279319.html
Copyright © 2011-2022 走看看