hdu 3864 D_num Pollard_rho算法和Miller_Rabin算法

时间:2022-11-29 14:37:04

D_num

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Problem Description
Oregon Maple was waiting for Bob When Bob go back home. Oregon Maple asks Bob a problem that as a Positive number N, if there are only four Positive number M makes Gcd(N, M) == M then we called N is a D_num. now, Oregon Maple has some Positive numbers, and if a Positive number N is a D_num , he want to know the four numbers M. But Bob have something to do, so can you help Oregon Maple? 
Gcd is Greatest common divisor.
 
Input
Some cases (case < 100);
Each line have a numeral N(1<=N<10^18)
 
Output
For each N, if N is a D_NUM, then output the four M (if M > 1) which makes Gcd(N, M) = M. output must be Small to large, else output “is not a D_num”.
 
Sample Input
6
10
9
 
Sample Output
2 3 6
2 5 10
is not a D_num
 
Source

题意:一个数的因数是否为4个;是,输出>1的因数;

思路:Pollard_rho算法和Miller_Rabin算法,前一个大质数分解,后面判断大数是否为质数;

   acdream的模板;

#include<iostream>
#include<cstdio>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstring>
#include<vector>
#include<list>
#include<set>
#include<map>
#include<bitset>
using namespace std;
#define LL unsigned long long
#define pi (4*atan(1.0))
#define eps 1e-4
#define bug(x) cout<<"bug"<<x<<endl;
const int N=,M=1e5+,inf=1e9+;
const LL INF=1e18+,mod=; const int Times = ;
LL ct, cnt;
LL fac[N], num[N]; LL gcd(LL a, LL b)
{
return b? gcd(b, a % b) : a;
} LL multi(LL a, LL b, LL m)
{
LL ans = ;
a %= m;
while(b)
{
if(b & )
{
ans = (ans + a) % m;
b--;
}
b >>= ;
a = (a + a) % m;
}
return ans;
} LL quick_mod(LL a, LL b, LL m)
{
LL ans = ;
a %= m;
while(b)
{
if(b & )
{
ans = multi(ans, a, m);
b--;
}
b >>= ;
a = multi(a, a, m);
}
return ans;
} bool Miller_Rabin(LL n)
{
if(n == ) return true;
if(n < || !(n & )) return false;
LL m = n - ;
int k = ;
while((m & ) == )
{
k++;
m >>= ;
}
for(int i=; i<Times; i++)
{
LL a = rand() % (n - ) + ;
LL x = quick_mod(a, m, n);
LL y = ;
for(int j=; j<k; j++)
{
y = multi(x, x, n);
if(y == && x != && x != n - ) return false;
x = y;
}
if(y != ) return false;
}
return true;
} LL pollard_rho(LL n, LL c)
{
LL i = , k = ;
LL x = rand() % (n - ) + ;
LL y = x;
while(true)
{
i++;
x = (multi(x, x, n) + c) % n;
LL d = gcd((y - x + n) % n, n);
if( < d && d < n) return d;
if(y == x) return n;
if(i == k)
{
y = x;
k <<= ;
}
}
} void Find(LL n, int c)
{
if(n == ) return;
if(Miller_Rabin(n))
{
fac[ct++] = n;
return ;
}
LL p = n;
LL k = c;
while(p >= n) p = pollard_rho(p, c--);
Find(p, k);
Find(n / p, k);
}
int main()
{
LL n;
while(~scanf("%I64d",&n))
{
ct = ;
Find(n, );
sort(fac, fac + ct);
num[] = ;
int k = ;
for(int i=; i<ct; i++)
{
if(fac[i] == fac[i-])
++num[k-];
else
{
num[k] = ;
fac[k++] = fac[i];
}
}
cnt = k;
LL ans = ;
if(cnt==)
{
if(num[]==)printf("%lld %lld %lld\n",fac[],fac[]*fac[],n);
else printf("is not a D_num\n");
}
else if(cnt==)
{
if(num[]==&&num[]==)printf("%lld %lld %lld\n",fac[],fac[],n);
else printf("is not a D_num\n");
}
else printf("is not a D_num\n");
//for(int i=0;i<cnt;i++)
//cout<<num[i]<<" "<<fac[i]<<endl;
}
return ;
}