poj 1811(随机化素数测试+素因子分解,涉及费马小定理,二次探测定理,Miller-Rabbin算法,pollard-rho算法)

复制代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath> 
#include<algorithm>
using namespace std;
#define ll long long
const int S = 20;
ll mult_mod(ll a,ll b,ll c){
    while(a>=c)a -= c;
    while(b>=c)b -= c;
    ll ans = 0;
    while(b>0){
        if(b&1) ans += a;
        while(ans>=c)ans -= c;
        a<<=1;
        while(a>=c)a-=c;
        b>>=1; 
    }
    return ans;
}
ll pow_mod(ll x,ll n,ll c){
    while(x>=c)x-=c;
    if(n==1)return x;
    ll ans = 1;
    ll tmp = x;
    while(n){
        if(n&1){
            ans = mult_mod(ans,tmp,c);
        }
        tmp = mult_mod(tmp,tmp,c); 
        n>>=1;
    }
    return ans;
}
//bool check(ll a,ll n,ll x,ll t){
//}
bool Miller_Rabin(ll n){
    if(n==2)return true;
    if(n<2)return false;
    if((n&1)==0)return false;
    ll x = n-1,t = 0;
    while((x&1)==0)x>>=1,t++;
    for(int i=0;i<S;i++){
        ll a = rand()%(n-1)+1;
        ll ans = pow_mod(a,x,n);
        ll last = ans;
        for(ll j=1;j<=t;j++)
        {
            ans=mult_mod(ans,ans,n);
            if(ans==1&&last!=1&&last!=n-1) return false;//合数
            last=ans;
        }
        if(ans!=1) return false;
    }
    return true;
} 
ll factor[100];
ll total;
ll gcd(ll a,ll b){
    if(a==0)return b;
    if(a<0) return gcd(-a,b);
    ll t;
    while(b)
    {
        t=a%b;
        a=b;
        b=t;
    }
    return a;
}
ll Pollard_rho(ll x,ll c){
    ll i=1,k=2;
    ll x0=rand()%x;
    ll y=x0;
    while(1)
    {
        i++;
        x0=(mult_mod(x0,x0,x)+c)%x;
        ll d=gcd(y-x0,x);
        if(d!=1&&d!=x) return d;
        if(y==x0) return x;
        if(i==k){y=x0;k<<=1;}
    }
}
void findfac(ll n){
    if(Miller_Rabin(n))//素数
    {
        factor[total++]=n;
        return;
    }
    ll p=n;
    while(p>=n)p=Pollard_rho(p,rand()%(n-1)+1);
    findfac(p);
    findfac(n/p);
}
int main(){
    ll t,n,i,ans;
    bool flag;
    scanf("%lld",&t);
    while(t--){
        scanf("%lld",&n);
        total = 0;
        if(Miller_Rabin(n))
            printf("Prime\n");
        else{
            findfac(n);
            ans = factor[0];
            for(i=1;i<total;i++){
                if(factor[i]<ans){
                    ans = factor[i];
                }
            }
            printf("%lld\n",ans);
        }
    }
    return 0;
}
复制代码

 

posted @   智人心  阅读(67)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示