您的位置:首页 > 其它

poj 1811 Prime Test_Pollard_rho算法模板

2014-04-24 13:27 453 查看
题目链接

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

思路:套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; 
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: