hrbust1353 LCM与数对

题意:求出以n为最小公倍数的不同正整数对(uv)的个数。(1 ≤ n ≤ 1012)

注:对于u ≠ v,数对(uv)与(vu)被视为不同的。

思路:n=p1^a1 * p2^a2 * p3^a3 * ……其中p1,p2,p3……是n的素因子,a1是p1的指数。

欲使(u,v)的最小公倍数是n,那么
        u=p1^b1 * p2^b2 * p3^b3 * ……

        v=p1^c1 * p2^c2 *  p3^c3 * ……

其中满足(bi=ai&&ci<=ai)或者(ci=ai&&bi<=ai)。

如果u=v且最小公倍数等于n,那么一定是u=v=n。由于对于u ≠ v,数对(uv)与(vu)被视为不同的。

所以(bi,ci)的组合情况为2*(ai+1)-1=2*ai+1种。

答案就是    ∏(2*ai+1)。

View Code
 1 #include <stdio.h>
 2 #include <string.h>
 3 const int MAXN=1000011;
 4 long long prime[MAXN+10];
 5 int getPrime(){
 6     memset(prime,0,sizeof(prime));
 7     for(int i=2;i<=MAXN;i++){
 8         if(!prime[i]) prime[++prime[0]]=i;
 9         for(int j=1;j<=prime[0]&&prime[j]<=MAXN/i;j++){
10             prime[prime[j]*i]=1;
11             if(i%prime[j]==0) break;
12         }
13     }
14     return prime[0];
15 }
16 int main(){
17     getPrime();
18     long long T,n,m,res,top,cnt;
19     scanf("%lld",&T);
20     while(T--){
21         scanf("%lld",&n);
22         m=n;top=res=1;cnt=0;
23         if(n!=1)
24         while(1){
25             if(prime[top]*prime[top]>m){
26                 res*=3;break;
27             }
28             if(n%prime[top]!=0){
29                 res*=(1+2*cnt);
30                 cnt=0;
31                 top++;
32                 if(n==1) break;
33             }
34             if(n%prime[top]==0){
35                 n/=prime[top];
36                 cnt++;
37             }
38         }
39         printf("%lld\n",res);
40     }
41     return 0;
42 }

 

 

posted @ 2013-02-05 02:59  _sunshine  阅读(245)  评论(0编辑  收藏  举报