先看题目:
F(X)
题目详情
我们定义 F(x)是满足 x mod(a*b) == 0这样的a,b的组数。现在给你一个n,你需要求出 F(n)
输入格式:
多组数据,每组第一行有一个整数n, 0 < n <= 10^11。
输出格式:
每组输出一行,满足条件的(a,b)对数
答题说明
输入样例
1
2
3
4
输出样例:
1
3
3
6
解释
第一组: (1,1)
第二组: (1,1) (1,2) (2, 1)
第三组: (1,1) (1,3) (3,1)
第四组: (1,1) (1,2) (1, 4) (2, 1) (2,2) (4,1)
解题思路:
对于数n,f(n)=1+不包含1的约数个数*2+不包含1和本身的约数个数,那么这道题就转化为求解n的约数个数
求n的约数个数,可以先把n分解成质因数的乘积,比如6=2*3,8=2*2*2,360=2*2*2*3*3*5
这样就又转换成从几个集合中取若干个的可能性。
举例来说:360分解成了3个集合p[2]=3,p[3]=2,p[5]=1
第一个集合有3个,第二个集合有2个,这两个集合合并形成新的集合=集合一+集合二+集合一*集合二,(3+2+3*2)=11
第三个集合和新集合合并,按照上述计算方式计算(11+1+11*1)=23
。。。。。
360的不包含1的约数个数=23个
所以f(360)=1+23*2+23-1=23*3=69
这里需要注意,1属于特例,直接返回1
代码如下:
public static int run(long n)
{
if (n == 1)
return 1;
int count = 0;
long x = n;
Dictionary<long, int> primeList = new Dictionary<long, int>();
int i = 2;
#region 分解质因数集合
while (x > 1)
{
if (i * i > x)
{
if (primeList.ContainsKey(x))
{
primeList[x]++;
}
else
{
primeList.Add(x, 1);
}
break;
}
if (x % i == 0)
{
if (primeList.ContainsKey(i))
{
primeList[i]++;
}
else
{
primeList.Add(i, 1);
}
x /= i;
}
else
{
i++;
}
}
#endregion
foreach (KeyValuePair<long, int> kvp in primeList)
{
count = count + kvp.Value + count * kvp.Value;
}
count = count * 3;
return count;
}