质因数分解
重要数论函数






欧拉函数
求单个phi值:
int Euler(int n) { LL k = (LL)sqrt(n + 0.5); LL ans = n; for(int i=2; i<=k; ++i){ if(n%i == 0){ ans = ans / i * (i-1); //ans -= ans/i; while(x%i == 0) n /= i; } } //最后只剩下 小于4的素数 或者n本身就是素数 if(n > 1) ans = ans / n * (n-1); // ans -= ans/i; return ans; }
欧拉筛
void euler(int n) { phi[1]=1; //1要特判 int cnt = 0; for (int i=2;i<=n;i++){ if (flag[i]==0){ //这代表i是质数 prime[++cnt]=i; phi[i]=i-1; } for (int j=1;j<=cnt&&prime[j]*i<=n;j++){ flag[i*prime[j]]=1; //先把这个合数标记掉 if (i%prime[j]==0){ phi[i*prime[j]]=phi[i]*prime[j]; //若prime[j]是i的质因子,则根据计算公式,i已经包括i*prime[j]的所有质因子 break; //经典欧拉筛的核心语句,这样能保证每个数只会被自己最小的因子筛掉一次 } else phi[i*prime[j]]=phi[i]*phi[prime[j]]; //欧拉函数是个积性函数的性质 } } }
莫比乌斯函数
求单个miu值
LL getmiu(int n){ int k = 0; for(LL i=2; i*i<=n; ++i){ if(n%i == 0){ ++ s; int cnt = 0; while(n%i == 0){ //质因数分解 n /= i; ++ cnt; } if(cnt >= 2) return 0; //超过一个相同因子,则为0 } } if(n > 1) ++ s; //唯一大于sqrt(n)的质因子 if(s & 1) return 1; //(-1)^s, 奇数返回1,否则0 return 0; }
筛法
void miu(int n){ miu[1] = 1; int cnt = 0; for(int i=2; i<=n; ++i){ if(!flag[i]){ miu[i] = -1; pri[++cnt] = i; } for(int j=1; j<=cnt&&i*pri[j]<=n; ++j){ flag[i*pri[j]] = true; if(i%pri[j] == 0){ miu[i*pri[j]] = 0; break; } miu[i*pri[j]] = -miu[i]; } } }
来源:https://blog.csdn.net/weixin_42318552/article/details/99676660