HDU3988 大整数质因数分解【Miller_Rabin 进行素数判定+Pollard_rho对整数进行因数分解】

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sxy201658506207/article/details/84676996

iSea is tired of writing the story of Harry Potter, so, lucky you, solving the following problem is enough. 

Input
The first line contains a single integer T, indicating the number of test cases. 
Each test case contains two integers, N and K. 
Technical Specification 
1. 1 <= T <= 500 
2. 1 <= K <= 1 000 000 000 000 00 
3. 1 <= N <= 1 000 000 000 000 000 000 
Output
For each test case, output the case number first, then the answer, if the answer is bigger than 9 223 372 036 854 775 807, output “inf” (without quote).
Sample Input
2
2 2
10 10
Sample Output
Case 1: 1
Case 2: 2
 

#include <bits/stdc++.h>
#define X 10005
#define inF 0x3f3f3f3f
#define PI 3.141592653589793238462643383
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
typedef long long ll;
const int N = 1e4;
const int Times=10;
const ll inf= 9223372036854775807;
ll ct,cnt;
ll fac[N],num[N];
ll gcd(ll a,ll b)
{
    if(!b)
        return a;
    else
        gcd(b,a%b);
}
ll mul_mod(ll a,ll b,ll m)
{
    ll ans=0;
    while(b)
    {
        if(b&1)
        {
            ans=(ans+a)%m;
        }
        a=(a+a)%m;
        b>>=1;
    }
    return ans;
}
ll Pow_mod(ll a, ll b,ll m)
{
    ll ans=1;
    a%=m;
    while(b)
    {
        if(b&1)
        {
            ans=mul_mod(ans,a,m);//ans=ans*a%m;
        }
        a=mul_mod(a,a,m);//a=a*a%m;
        b>>=1;
    }
    return ans;
}
bool Miller_Rabin(ll n)
{
    if(n==2)
        return true;
    if(n<2||!(n&1))
        return false;
    ll a,m=n-1,x,y;
    int k=0;
//    while((m&1)==0)//判奇数
//    {
//        k++;
//        m>>=1;
//    }
    while (~m & 1) //找到奇数
    {
        m >>= 1;
        k++;
    }
    for(int i=0;i<Times;++i)
    {
        a=rand()%(n-1)+1;
        x=Pow_mod(a,m,n);
        for(int j=0;j<k;++j)
        {
            y=mul_mod(x,x,n);
            if(y==1&&x!=1&&x!=n-1)
                return false;
            x=y;
        }
        if(y!=1)  //a^(2*k*r)%m=1
            return false;
    }
    return true;
}
ll f(ll x,ll n)
{
    return (mul_mod(x,x,n)+2)%n;
}
ll Pollard_rho(ll n,ll c)
{
    ll x,y,d,i=1,k=2;
    y=x=rand()%(n-1)+1;
    while(true)
    {
        i++;
        x=f(x,n);//x=(mul_mod(x,x,n)+c)%n;
        d=gcd((y-x+n)%n,n);
        if(1<d&&d<n)
            return d;
        if(y==x)
            return n;//没有随机查找素因子失败,返回
        if(i==k)
        {
            y=x;
            k<<=1;
        }
    }
//    do
//    {
//        i++;
//        x=f(x,n);//(mul_mod(x,x,n)+c)%n;
//        d=gcd((y-x+n)%n,n);
//        if(1<d&&d<n)
//            return d;
////        if(y==x)
////            return n;//没有随机查找素因子失败,返回
//        if(i==k)
//        {
//            y=x;
//            k<<=1;
//        }
//    }while(y!=x);
    return n;
}
ll get(ll p,ll n)
{
    ll ans=0;
    while(n)
    {
        ans+=n/p;///    no
        n/=p;
    }
    return ans;
}
void Find(ll n,int c)
{
    if(n==1)
        return ;
    if(Miller_Rabin(n))
    {
        fac[ct++]=n;
        return ;
    }
    ///不是素数:
    ll p = n, k = c;
    while(p>=n)
        p = Pollard_rho(p,c);///找到n的一个因子,但是现在还不能保证是一个素因子,要进行Miller_rabin素数检测
    Find(p,k);
    Find(n/p,k);//因为n是偶数
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int t=1,tt=1;
    ll n,k,minx;
    cin>>t;
    for(int Case=1;Case<=t;++Case)
    {
        cin>>n>>k;
        cout<<"Case "<<Case<<": ";
        if(k==1)
        {
            cout<<"inf"<<endl;
            continue;
        }
        ct=0;
        Find(k,2);
        sort(fac,fac+ct);
        num[0]=1;
        int k=1;
        for(int i=1;i<ct;++i)
        {
            if(fac[i]==fac[i-1])
            {
                num[k-1]++;
            }
            else
            {
                num[k]=1;
                fac[k++]=fac[i];
            }
        }
        cnt=k;
        minx=inf;
        for(int i=0;i<cnt;++i)
        {
            ll tmp=get(fac[i],n)/num[i];
            minx=min(minx,tmp);
        }
        if(minx==inf)
            cout<<"inf"<<endl;
        else
            cout<<minx<<endl;
    }
    return 0;
}

/*
    对大整数进行质因数分解 采用  Miller_Rabin 进行素数判定 +  Pollard_rho 对整数进行因数分解(Mill_Rabin 判定是否是素数因子)
*/

猜你喜欢

转载自blog.csdn.net/sxy201658506207/article/details/84676996