hdu 5447 大数素数

传送门

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  nT=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(T10) . There will be  T  test cases. For each test case, there are two positive integers  k1  and  k2(1k1,k21024) 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
hujie   |   We have carefully selected several similar problems for you:   6079  6078  6077  6076  6075 
 
题意:假设有一个数K,如果有个小于等于K的数n和K的所有质因子相同,那么他们就是一对good numbers,现在给你K1和K2,他们的范围是1到10^24,让你求他们俩的各自的good number的个数。但是K1和K2存在一个非常有趣的关系,就是他们俩的最大质因子一定是相同的,两个第二大的质因子一定不同。

来自: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);
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值