LCM Cardinality
Input: Standard Input
Output: Standard Output
Time Limit: 2 Seconds
A pair of numbers has a unique LCM but a single number can be the LCM of more than one possible pairs. For example 12 is the LCM of (1, 12), (2, 12), (3,4) etc. For a given positive integer N, the number of different integer pairs with LCM is equal to N can be called the LCMcardinality of that number N. In this problem your job is to find out the LCM cardinality of a number.
The input file contains at most 101 lines of inputs. Each line contains an integer N (0<N<=2*109). Input is terminated by a line containing a single zero. This line should not be processed.
For each line of input except the last one produce one line of output. This line contains two integers N and C. Here N is the input number and Cis its cardinality. These two numbers are separated by a single space.
2 12 24 101101291 0 |
2 2 12 8 24 11 10110129 |
题意:给出a和b的最小公倍数N,找出符合条件的a、b有多少对。
分析:1. 设n = LCM(a,b) = (p1^r1) * (p2^r2) * (p3^r3) … (pm^rm)
又设a=(p1^a1) * (p2^a2) * (p3^a3) … (pm^am),
b=(p1^b1) * (p2^b2) * (p3^b3)… (pm^bm)
由LCM的定义有ri = max{ai, bi}
所以对于每个ri,ai和bi中至少有一个要取ri
2. 对于ai取ri的情况,bi可以取[0,ri-1]的任意整数,这有ri种情况;
bi取ri的情况同样是ri种 。
最后加上ai和bi都取ri的情况,共有(2*ri+1)种情况
3. 由于这么考虑把(a,b)和(b,a)算重复了,但(n,n)的情况只算了一遍,所以最后要ans= (ans+1)/2=ans/2+1(因为ans是奇数)
4. 优化:只考虑√n范围内的质数,但这样会存在漏掉一个大质数的情况(比如n=2*101) ,这个大质数的幂次只能为1(即少算了一个*(2*1+1)),所以在这种情况发生时要补上ans*=3,写成 位运算就是ans+=ans<<1。
#include <cstdio> #include <cmath> int n; void get_ans() { int tmp = n; int m = (int)sqrt(n + 0.5); long long ans = 1; for(int i = 2; i <= m; i += 2) { if(n % i == 0) { int cnt = 0; while(n % i == 0) { n /= i; cnt++; } ans *= (cnt << 1) + 1; } if(i == 2) i--; } if(n > 1) ans += (ans<<1); ans = (ans >> 1) + 1; printf("%d %lld\n", tmp, ans); } int main() { while(~scanf("%d", &n) && n) { get_ans(); } return 0; }