分解质因数

[复制链接]
发表于 2024-1-2 17:59:55 | 显示全部楼层 |阅读模式

以下两行表示 np1a1p2a2…pkak,其中 p1、p2…pk n 的质因数。
int n; int p[N], a[N], k;
(1) 分解质因数
file:///C:/Users/123/AppData/Local/Temp/ksohtml11960/wps21.png方法一:产生一个从2到n的质数表,然后从2开始除。在除干净之后换下一个因数。
方法二:不产生质数表,直接从2开始除。在除干净之后换下一个因数。(注:n 是素数时速度会非常慢。)
int i=2; top=-1; while (n>1)
{
if (n%i==0)
{
  p[++k]=i;   a[k]=0;
第十二单元 数论算法
  while (n%i==0) n/=i, a[k]++;
}
else   i++;     // 换下一个因数(提示:如果上面的n%i==0为真,那么i肯定是质数)
}
分解质因数的实际应用是使用因数表优化乘除法。
(2) 除数函数 d(n) n 的所有因数的个数,由乘法原理可知,
d(n)=(a1+1)(a2+1)…(ak+1)。
(3) 欧拉函数
设φ(n)为1,2,3,…n 中与 n 互素的元素个数,那么φ(n)可以用容斥原理计算。但是容斥原理比较复杂,计算速度也非常慢。所以要用另一种形式求解:
φ(n)=n(1-1)(1-1)…(1-1)=n·p1p21·…·pk1) p1        p2        pk        p1        p2        pk
可以直接计算:
int phi(int n)
{  int m = (int)sqrt(n);  int ans=n;
// 这里是边分解质因数边计算。如果已经分解质因数,就可以直接计算了。  for (int i=2;i<=m;i++)   if (n%i==0)
  {
   ans=ans / i * (i-1);    while (n%i==0) n/=i;
  }
if (n>1) ans=ans / n * (n-1);   // 防质数  return ans;
}
如果要产生欧拉函数表,可以用递推的方法完成:
void phi_table(int *a, int n)
{  memset(a,0,sizeof(int)*(n+1));  a[1]=1;
  
for (int i=2; i<=n; i++)   if (!a)    for (int j=1; j<=n; j+=i)
   {
    if (!a[j]) a[j]=j;     a[j]=a[j]/i*(i-1)
   }
}


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表