LightOJ 1236 Pairs Forming LCM (算术基本定理)

来源:互联网 发布:尤克里里软件怎么调音 编辑:程序博客网 时间:2024/05/01 16:11

题目传送门:点击打开链接

这题要求a,b两个数的最小公倍数等于n的对数,其中a,b<=n并且a,b 都是n的因子;

根据算术基本定理:n=p1^x1*p2^x2*p3^x3*p4^x4...

a=p1^a1*p2^a2*p3^a3*p4^a4.....

b=p1^b1*p2^b2*p3^b3*p4^b4.....

其中pi为素数

如果a,b的公倍数为n,那么n=p1^max(a1,b1)*p2^max(a2,b2)*p3^max(a3,b3)*p4^max(a4,b4)....

以p1 为例,max(a1,b1)=x1,要么a1=x1 或者 b1=x1或者a1=b1=x1;其他也是这样。

所以对于a和b他们的a1,b1至少有一个为x1, 我们假设a的a1=x1,那么b1有可能为 (0-x1) 符合max(a1,b1)=x1,就是x1+1中可能,如果换过来又有x1+1中可能,但是这两种情况算了x1=a1=b1两次,所以对与p1就有 2*x1+1中可能。p2就有2*x2+1,p3  2*x3+1,p4  2*x4+,pi  2*xi+1可能,所以当lcm(a,b)的对数的可能数为ans=(2*x1+1)*(2*x2+1)*(2*x3+1)...*(2*xi+1)...

但是我们可以想到  我们所得的结果有重复的 像(1,2),(2,1) 是一种我们算成两种,但是有一个例外就是(n,n)我们就算一种,所以这题的正确答案(ans+1)/2,1 代表我们再补上(n,n)这种情况  那么所有情况都算了两次,所以我们除以2就是一遍了。。

#include <iostream>#include <cstring>using namespace std;const int MAXSIZE=1e7;const int maxn=1e6;bool Mark[MAXSIZE];int prime[maxn];int inde = 0;long long ans,n;void Prime(){    memset(Mark,0,sizeof(Mark));    for(int i = 2; i < MAXSIZE; i++)    {        if(Mark[i] == 0){            prime[inde++] = i;        }        for(int j = 0; j < inde && prime[j] * i < MAXSIZE; j++)        {            Mark[i * prime[j]] = 1;            if(i % prime[j] == 0){                break;            }        }    }}void solve(){    ans=1;long long tmp;    for(int i=0;i<inde&&prime[i]*prime[i]<=n;++i)    {        if(!(n%prime[i]))        {            tmp=0;            while(!(n%prime[i]))            {                n/=prime[i];                ++tmp;            }            ans*=(1+2*tmp);        }    }    if(n!=1)        ans*=3;        //cout<<"    "<<ans<<endl;}int main(int argc, const char * argv[]){    int t,cnt=0;    Prime();    cin>>t;    while(t--)    {        cin>>n;        //for(int i=1e7;i<=1e8;++i)        //{            solve();            cout<<"Case "<<++cnt<<": "<<(ans+1)/2<<endl;        //}            }    return 0;}

                                                                     Pairs Forming LCM                                                                                                                              
Time Limit: 2000MSMemory Limit: 32768KB64bit IO Format: %lld & %llu

Submit Status uDebug

Description

Find the result of the following code:

long long pairsFormLCM( int n ) {
    long long res = 0;
    for( int i = 1; i <= n; i++ )
        for( int j = i; j <= n; j++ )
           if( lcm(i, j) == n ) res++; // lcm means least common multiple
    return res;
}

A straight forward implementation of the code may time out. If you analyze the code, you will find that the code actually counts the number of pairs (i, j) for which lcm(i, j) = n and (i ≤ j).

Input

Input starts with an integer T (≤ 200), denoting the number of test cases.

Each case starts with a line containing an integer n (1 ≤ n ≤ 1014).

Output

For each case, print the case number and the value returned by the function 'pairsFormLCM(n)'.

Sample Input

15

2

3

4

6

8

10

12

15

18

20

21

24

25

27

29

Sample Output

Case 1: 2

Case 2: 2

Case 3: 3

Case 4: 5

Case 5: 4

Case 6: 5

Case 7: 8

Case 8: 5

Case 9: 8

Case 10: 8

Case 11: 5

Case 12: 11

Case 13: 3

Case 14: 4

Case 15: 2



0 0