Good Numbers
Time Limit: 3000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1310 Accepted Submission(s): 238
Problem Description
Kyrie is a programmer highly interested in math. He likes to design math games for himself to play. One day, he defined that “a positive integer u is under good relation with another positive integer
v
” if the set of all prime factors of
u
and the set of all prime factors of
v
are the same. For example, 6 is under good relation with 12, since the set of all prime factors of both 6 and 12 are the same.
Now he has a number k , he tries to find all numbers that are under good relation with k . However, he then unfortunately discovers the fact that there are infinite integers which satisfy this condition. Therefore, Kyrie defines: For a positive integer n , if there exist an integer T that satisfies n⋅T=k and n is under good relation with k at the same time, then he will say “ n is good.”
Kyrie is now very happy seeing that there are only finite “good numbers” no matter what the value of k is. He decides to invite his friend Erik to play the math game together. They pick k1 and k2 and try to find their own “good number” accordingly. Assume there is a surprising miracle that k1 and k2 have the same greatest prime factor, and what’s more, second large prime factor of k1 is not a factor of k2 and the second large prime factor of k2 is also not a factor of k1 .
Write a program to find out how many “good number” there are under k1 and k2 .
Now he has a number k , he tries to find all numbers that are under good relation with k . However, he then unfortunately discovers the fact that there are infinite integers which satisfy this condition. Therefore, Kyrie defines: For a positive integer n , if there exist an integer T that satisfies n⋅T=k and n is under good relation with k at the same time, then he will say “ n is good.”
Kyrie is now very happy seeing that there are only finite “good numbers” no matter what the value of k is. He decides to invite his friend Erik to play the math game together. They pick k1 and k2 and try to find their own “good number” accordingly. Assume there is a surprising miracle that k1 and k2 have the same greatest prime factor, and what’s more, second large prime factor of k1 is not a factor of k2 and the second large prime factor of k2 is also not a factor of k1 .
Write a program to find out how many “good number” there are under k1 and k2 .
Input
The first line on the input contains an integer
T(T≤10)
. There will be
T
test cases. For each test case, there are two positive integers
k1
and
k2(1≤k1,k2≤1024)
will be given in a line.
Output
Print two numbers to represent how many good numbers can the two people find in one line for each test case. It is guaranteed that the answer will not exceed
1018
.
Sample Input
4 21 35 20 15 37128 32725 637000 707850
Sample Output
1 1 2 1 3 2 18 8
Source
Recommend
来自:51nod tls的讲解
#include <string>
#include <cmath>
#include <algorithm>
const int maxx=1e6+100;
int tot,pr[maxx],vis[maxx],ans1,ans2;
__int128_t v1,v2;
template<class T> void Scan(T &x)
{
static int CH;
while((CH=getchar())<'0'||CH>'9');
for(x=CH-'0';(CH=getchar())>='0'&&CH<='9';x=(x<<3)+(x<<1)+(CH-'0'));
}
void init()
{
for(int i=2;i<maxx;i++)
{
if(!vis[i])pr[tot++]=i;
for(int j=0;j<tot&&i*pr[j]<maxx;j++)
{
vis[i*pr[j]]=1;
if(i%pr[j]==0)break;
}
}
}
bool issqr(__int128_t x)
{
__int128_t y=(__int128_t)ceil(sqrt((long double)x));
for(;y*y<=x;++y);
for(--y;y*y>x;--y);
return y*y==x;
}
bool iscub(__int128_t x)
{
__int128_t y=(__int128_t)ceil(pow((long double)x,1.0/3));
for(;y*y*y<=x;++y);
for(--y;y*y*y>x;--y);
return y*y*y==x;
}
void upd(int &ans,__int128_t L,__int128_t R)
{
if(R==1)
ans*=L==1?1:(iscub(L)?3:(issqr(L)?2:1));//(1,1) (p1^3,1) (p1^2,1) (p1,1)
else if(issqr(R))
ans*=R%L?2:3;//(p1,p2^2) (p1,p1^2)
else if(issqr(L))//r>1
ans*=L%R?2:3;//(p1%2,p2) (p1^2,p1)
else if(R%L==0)
ans*=L==R?2:2;//(p1,p1) (p1,p1 p2)
else if(L<R)
ans*=1;//(p1,p2 p3)
else ans*=1;//(p1,p2) (p1 p3,p2)
}
int main()
{
init();
int t;
Scan(t);
while(t--)
{
Scan(v1);Scan(v2);
ans1=ans2=1;
for(int i=0;i<tot;i++)
{
if(v1%pr[i]==0)
{
int cnt=0;
for(;v1%pr[i]==0;v1/=pr[i],++cnt);
ans1*=cnt;
}
if(v2%pr[i]==0)
{
int cnt=0;
for(;v2%pr[i]==0;v2/=pr[i],++cnt);
ans2*=cnt;
}
}
__int128_t r=std::__gcd(v1,v2);
upd(ans1,r,v1/r);
upd(ans2,r,v2/r);
printf("%d %d\n",ans1,ans2);
}
}