#include <cstdio>
#include <cstring>
const int maxn = 1E5 + 10;
const int INF = 0x3f3f3f3f;
int visit[maxn], prime[maxn], kase, T, m, n;
int getprime()
{
memset(visit, 0, sizeof(visit));
int cnt = 0;
for (long long i = 2; i < maxn; i++)
if (!visit[i])
{
prime[cnt++] = i;
for (long long j = i * i; j < maxn; j += i)
visit[j] = 1;
}
return cnt;
}
int main(int argc, char const *argv[])
{
int cnt = getprime();
while (~scanf("%d", &n) && n)
{
long long ans = 1;
printf("%d ", n);
for (int i = 0; n > 1 && i < cnt; i++)
{
int k = 0;
while (n % prime[i] == 0)
n /= prime[i], k++;
ans *= k * 2 + 1;
}
ans = ans / 2 + 1;
printf("%lld\n", ans);
}
return 0;
}
题目:给你一个数字N,问有多少对不同的a,b的最小公倍数数N。
分析:数论,组合数学。因式分解,然后计数。
首先打表,计算100000内的素数,然后用试除法求出每个素因子个数;
那么对于每个素数因子pi,设有k个pi则可能的组合为:
(1,pi^k),(pi,pi^k),...(pi^k,pi^k)及(pi^k,1),(pi^k,pi),...(pi ^k,pi^k)
因此有2k+1对,所以结果为π(2ki+1);
这里注意如果a,b不同则会计算重复,因此去掉排列后的结果为 π(2ki+1)/ 2 + 1;
(最后加的1是因为a = b = n时只计算了一次)