题目描述:
rin最近喜欢上了数论。
然而数论实在太复杂了,她只能研究一些简单的问题。
这天,她在研究正整数因子个数的时候,想到了一个“快速迭代”算法。设f(X) 为X的因子个数,将f迭代下去,rin猜想任意正整数最终都会变成 2。
例如: f(12) = 6, f(6) = 4, f(4) = 3, f(3) = 2。
她希望你帮她验证一下。她会给你一个正整数n ,让你输出它在迭代过程中,第一次迭代成2的迭代次数。
输入描述:
一个正整数n (3 <= n <= 10^12)
输出描述:
一个正整数,为n迭代至2的次数
分析:
此题应用了数论中以下知识点:
- 求取一个数的质因子
- 利用质因子来求取因子
假设正整数为N,因子的个数为M
对任意正整数N,分解质因数得到:N = P1^X1 * P2^X2 * …… * Pn^Xn
(P1 P2 … Pn均为N的质因数,X1 X2 … Xn为质因数对应的次数)
正整数N因子的个数:M = (X1 + 1) * (X2 + 1) * … * (Xn + 1);
代码如下:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <map>
#include <cmath>
using namespace std;
long long n;
const int MAXN = 1e4 + 5;
int prim[MAXN],ind;
long long res;
map<int,int> numPri;
long long FindPrim(long long nb)
{
ind = 0;
memset(prim,0,sizeof(prim));
int sqrtN = sqrt(nb);
for(int i=2;i<=sqrtN;++i)
if(nb % i == 0)
{
prim[++ind] = i;
while(nb % i == 0)
{
nb /= i;
++numPri[i];
}
}
if(nb > 1)
{
prim[++ind] = nb;
numPri[nb] = 1;
}
int ans=1;
for(int i=1;i<=ind;++i)
{
ans *= numPri[prim[i]] + 1;
numPri[prim[i]] = 0;
}
return ans;
}
int main()
{
scanf("%lld",&n);
int ans = 0;
res = n;
while(res != 2)
{
res = FindPrim(res);
++ans;
}
printf("%d\n",ans);
return 0;
}