题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3864
题目:
D_num
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 921 Accepted Submission(s): 249
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.
Gcd is Greatest common divisor.
Input
Some cases (case < 100);
Each line have a numeral N(1<=N<10^18)
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
Recommend
lcy
题目意思很简单了主要难的地方在于数据量太大,所以必须用随机算法
但是要注意一种特殊情况,及某质数的三次方。
我的代码:
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<time.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
#define MAX_VAL __int64(1)<<60
#define TIMES 40
#define MAX_L 64n
#define CVAL 200
typedef __int64 LL;
using namespace std;
LL minfactor;
LL multandmod(LL a,LL b,LL n)
{
a=a%n;
LL res=0;
while(b)
{
if(b&1)
{
res=res+a;
if(res>=n)
res=res-n;
}
a=a<<1;
if(a>=n)
a=a-n;
b=b>>1;
}
return res;
}
LL modandexp(LL a,LL b,LL n)
{
a=a%n;
LL res=1;
while(b>=1)
{
if(b&1)
res=multandmod(res,a,n);
a=multandmod(a,a,n);
b=b>>1;
}
return res;
}
bool millerRobin(LL a,LL n)
{
LL u=0,cur=n-1;
int t=0;
bool find1=false;
while(cur!=0)
{
if(!find1)
{
int pb=cur%2;
if(pb==0)
t++;
else
find1=true;
}
if(find1)
break;
cur=cur/2;
}
u=cur;
cur=modandexp(a,u,n);
LL now;
for(int p=1;p<=t;p++)
{
now=modandexp(cur,2,n);
if(cur!=1&&now==1&&cur!=n-1)
{
return false;
}
cur=now;
}
if(cur!=1)
return false;
return true;
}
bool testprime(int times,LL n)
{
if(n==2)
return true;
if(n%2==0)
return false;
LL a;int t;
srand(time(NULL));
for(t=1;t<=times;t++)
{
a=rand()%(n-1)+1;
if(!millerRobin(a,n))
return false;
}
return true;
}
LL gcd(LL a,LL b)
{
if(b==0)
return a;
else
return gcd(b,a%b);
}
LL pollardrho(LL n,int c)
{
int i=1;
srand(time(NULL));
LL x=rand()%n;
LL y=x;
int k=2;
while(true)
{
i=i+1;
x=(modandexp(x,2,n)+c)%n;
LL d=gcd(y-x,n);
if(1<d&&d<n)
return d;
if(y==x)
return n;
if(i==k)
{
y=x;
k=k*2;
}
}
}
void getsmallst(LL n,int c)
{
if(n==1)
return;
if(testprime(TIMES,n))
{
if(n<minfactor)
minfactor=n;
return;
}
LL val=n;
while(val==n)
val=pollardrho(n,c--);
getsmallst(val,c);
getsmallst(n/val,c);
}
int main()
{
LL n;
while(scanf("%I64d",&n)!=EOF)
{
minfactor=MAX_VAL;
if(n==1)
{
printf("is not a D_num\n");
continue;
}
if(testprime(TIMES,n))
printf("is not a D_num\n");
else
{
getsmallst(n,CVAL);
if(minfactor*minfactor*minfactor==n)
{
printf("%I64d %I64d %I64d\n",minfactor,minfactor*minfactor,n);
continue;
}
if(minfactor*minfactor==n)
{
printf("is not a D_num\n");
continue;
}
if(testprime(TIMES,n/minfactor))
printf("%I64d %I64d %I64d\n",minfactor,n/minfactor,n);
else
printf("is not a D_num\n");
}
}
return 0;
}