题意:求出以n为最小公倍数的不同正整数对(u, v)的个数。(1 ≤ n ≤ 1012)
注:对于u ≠ v,数对(u, v)与(v, u)被视为不同的。
思路: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,数对(u, v)与(v, u)被视为不同的。
所以(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 }