poj 1811 Prime Test_Pollard_rho算法模板

来源:互联网 发布:防伪底纹制作软件下载 编辑:程序博客网 时间:2024/06/06 09:37

题目链接

题意:给你一个数,如果这个数是合数就输出它的最少因子

思路:套Pollard_rho算法模板

#include <cstdio>#include <cmath>#include <ctime>#include <cstdlib>#include <cstring>#include <string>#include <algorithm>#include <iostream>using namespace std;  #define LL long long #define MAX ((long long)1<<61)LL factor[200],cnt;LL mini; LL gcd(LL a,LL b) {      return (b==0)?a:gcd(b,a%b);  }  LL Mulmod(LL a,LL b,LL n) {    LL  exp = a%n, res = 0;      while(b) {        if(b&1) {            res+=exp;              if(res>n) res-=n;          }          exp <<= 1;          if(exp>n)              exp-=n;          b>>=1;      }      return res;  }    LL exp_mod(LL a,LL b,LL c){    LL k = 1;      while(b){        if(b&1)              k = Mulmod(k,a,c);          a = Mulmod(a,a,c);          b>>=1;      }      return k;  }  bool Miller_Rabin(LL n, LL times){    if(n==2)return 1;      if(n<2||!(n&1))return 0;        LL a, u=n-1, x, y;      int t=0;      while(u%2==0){          t++;          u/=2;      }      srand(100);      for(int i=0;i<times;i++){        a = rand() % (n-1) + 1;          x = exp_mod(a, u, n);          for(int j=0;j<t;j++){            y = Mulmod(x, x, n);              if ( y == 1 && x != 1 && x != n-1 )                  return false; //must not              x = y;          }          if( y!=1) return false;      }      return true;  }    LL Pollard_Rho(LL n,LL c){    LL x,y,d,i=1,k=2;      y = x = rand() % (n-1) + 1;      while(1){        i++;          x = (Mulmod(x,x,n) + c)%n;          d = gcd((x-y+n)%n,n);          if(d>1&&d<n)              return d;          if(x==y)              return n;          if(i==k){            k<<=1;              y = x;          }      }  }   void Find_factor(LL n,LL c)  {    if(n==1)          return;      if(Miller_Rabin(n,6)){        factor[cnt++] = n;         if(n<mini) mini=n;         return;      }      LL p = n;      LL k = c;      while(p>=n)          p = Pollard_Rho(p,c--);      Find_factor(p,k);      Find_factor(n/p,k);  }  int main(){    int t;      scanf("%d",&t);      LL n;      while(t--){          scanf("%lld",&n);        mini=MAX;        cnt=0;        if(Miller_Rabin(n,6)) puts("Prime");        else{            Find_factor(n,120);            printf("%lld\n",mini);        }    }    return 0; }


0 0