积性函数
积性函数
引入:
我们在线性筛质数的时候使用的方法是这样的
void GetPrime(int n){
memset(isPrime, 1, sizeof(isPrime));
isPrime[1] = 0;//1不是素数
for(int i = 2; i <= n; i++){
if(isPrime[i])
Prime[++cnt] = i;
for(int j = 1; j <= cnt && i*Prime[j] <= n; j++) {
isPrime[i*Prime[j]] = 0;
if(i % Prime[j] == 0)
break;
}
}
}
在这个程序里面我们保证一些东西:
1. 时候 一定是 的最小质因子
从小到大枚举
2. 中 一定是最小质因子
设
如果有更小的质因子
3. 一定被筛一次并且被他的最小质因子筛
积性函数:
定义:一个数是积性函数当且仅当:
而在积性函数中,经常使用到以下几个重要的积性函数(容易证明它们都是积性的):
•
•
•
•
积性函数一般搭配线性筛用
我在这里以
当
可以直接相乘
当
我们设
那么一定有
那么可以表示为
这样
但假如
那么
我们并没有算出
我们可以发现
函数值就直接等于
这样就有了以下代码
void pre(){
a[1] = 1;
for(int i = 2;i <= N; ++i){
isP[i] = 1;
}
for(int i = 2;i <= N; ++i){
if(isP[i] == 1){
prime[++tot] = i;
a[i] = 2;//如果是质数一定有两个因子
}
for(int j = 1;j <= tot && prime[j] * i <= N - 10; ++j){
isP[prime[j] * i] = 0;
if(i % prime[j] == 0){
int add = 0,sum = 0,x = i,y(prime[j]);
while(x % y == 0){
x = x / y;
add++;
}
a[prime[j] * i] = a[x] * (2 + add);
break;
}
a[prime[j] * i] = a[prime[j]] * a[i];
}
}
}
但时间复杂度变成了
我们记录
具体代码实现如下
void pre(){
a[1] = 1;
for(int i = 2;i <= N; ++i){
isP[i] = 1;
}
for(int i = 2;i <= N; ++i){
if(isP[i] == 1){
prime[++tot] = i;
a[i] = 2;//如果是质数一定有两个因子
add[i] = 1;//注意
}
for(int j = 1;j <= tot && prime[j] * i <= N - 10; ++j){
isP[prime[j] * i] = 0;
if(i % prime[j] == 0){
int x = i,y(prime[j]);
add[i * prime[j]] = add[i] + 1;//注意
a[prime[j] * i] = a[x/(add[i])] * (1 + add[i]);//注意
break;
}
a[prime[j] * i] = a[prime[j]] * a[i];
add[i * prime[j]] = 1;//注意
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现