特别基础的数论
本文主要讲了线性筛素数、分解质因数算法。
线性筛素数
这里只讲欧拉筛
算法思路:若是枚举到一个数,如果它没被标记成合数,那么加入素数数组,同时再用一个循环把所有小于x最小质因子的质数乘以x的数标记成合数。这样是有线性复杂度的。
既然是线性的正确算法,那应该能保证没漏筛、没重复筛。
证明:
设合数 有两个质因子
则 可以表示成
可以得到 。
那么我们就可以用 最小的质因子来筛掉 ,就只会筛一次。
不妨设 就是最小的质因子,那么 的最小的质因子一定大于等于 ,那么欧拉筛就一定在枚举到 能筛掉 。
但是在枚举到 时,因为它的最小的质因子一定大于 ,那么欧拉筛就不会筛到 。
综上所述, 当且仅当枚举到 时会被筛,所以就不会重复筛也不会漏筛。
代码:
#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e8+100;
bool isp[MAXN];
int prime[MAXN>>4],pcnt;
void init(int n) {
for(int i=2; i<=n; ++i) {
if(!isp[i])prime[++pcnt]=i;
for(int j=1,x; j<=pcnt&&(x=prime[j]*i)<=n; ++j) {
isp[prime[j]*i]=1;
if(!(i%prime[j]))break;
}
}
}
int main() {
int n,q;
scanf("%d%d",&n,&q);
init(n);
for(int i=1,x; i<=q; ++i) {
scanf("%d",&x);
printf("%d\n",prime[x]);
}
return 0;
}
分解质因数
这个可以做到将分解
可以发现,大于的质因数最多有一个,且指数一定为。
不然它们乘起来就大过了,所以我们可以只枚举的质因数。
先放代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN=40;
int p[MAXN],c[MAXN],pcnt,n;
void work(int n) {
for(int i=2; i*i<=n; ++i) {
if(!(n%i)) {//枚举到一个质因数
p[++pcnt]=i;//存下
while(!(n%i)) {//计算指数
n/=i;
++c[pcnt];
}
}//由于比这个因子更小的质因子都被除掉了
//所以这个因数一定是质因数
}
if(n>1) {//有大于根号n的质因数
p[++pcnt]=n;//存下
c[pcnt]=1;
}
}
int main() {
scanf("%d",&n);
work(n);
for(int i=1; i<=pcnt; ++i) {
printf("%d %d\n",p[i],c[i]);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】