Min_25 筛学习笔记
筛学习笔记
事实上我又学习了一个有点春的筛法。
众所周知,朴素筛法之所以无法做到低于线性是因为枚举了区间内的每一个数,那么我们想要做到低于线性,就必然需要做到通过一种方法将所有数字分成两类,用过一类的求解辅助另一类的求解,不难想到质数和合数。那么我们分开考虑如何求解质数和合数。对于
质数求解
首先考虑如何求解质数的贡献。众所周知,幂函数是一种完全积性函数,假若当
埃筛是一种复杂度略差于线性筛的筛法,但只表现为拥有较大的常数,在这里我们借鉴埃筛的思路。考虑埃筛利用每一个范围内的质数进行过滤,更具体的,对于每一个质数
那么考虑因为质数
接着考虑
不难发现可以用滚动数组优化掉第二维,但是时空复杂度依旧没有消下去。首先后半部分其实没有必要利用
合数求解
在求解完素数之后我们就要酝酿着统计合数对答案的贡献了。因为给定的函数是积性函数的缘故,因此我们可以将合数表示为最小质因子的次方和另一个数相乘的结果,因为后半部分的最小质因子不能小于原来的最小质因子,因此我们令
我们发现中间的求和可以用之前的质数前缀和快速求解,而剩余部分自行递归即可。整体的复杂度是
事实上在代码实现时,有一些不加不可的优化,和一些美化代码的优化,只能说自行选择了。代码以
代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define Get(x) (x<=S?id1[x]:id2[n/(x)])
#define f(p) (p)
const int N=1e5+5,P=1e9+7;
int S,cnt,tot;
int p[N],id1[N],id2[N];
ll n;
ll sum[N],g[N<<1],val[N<<1];//n/i 的值最多有 2sqrt(n) 个,结论不要记错了
bool isp[N];
void Euler_S(){
isp[1]=true;
for(int i=2;i<=S;i++){
if(!isp[i]){
p[++cnt]=i;
sum[cnt]=(sum[cnt-1]+i)%P;
}
for(int j=1;p[j]<=S/i;j++){
isp[i*p[j]]=true;
if(i%p[j]==0)continue;
}
}
return ;
}
ll SumF(ll a,int b){
if(a<=p[b])return 0;
int id=Get(a);
ll res=g[id]-sum[b];
for(int i=b+1;i<=cnt&&p[i]<=a/p[i];i++){//注意这里后半部分的判断是必加的,不加也能够得出正确答案,但因为常数过大被卡爆了
ll pk=p[i];
for(int j=1;pk<=a/p[i];j++,pk*=p[i])res=(res+f(pk)*SumF(a/pk,i)+f(pk*p[i]))%P;
//这部分和上面所说的转移方程略有不同,因为考虑到如果 pk*p>a,那么调用过去答案一定为 0,那么就没有必要进行这次操作
//并且后半部分变成 f(p^(j+1)),这样既能够避免重复统计质数,也能刚好覆盖到最大的数,同时能够保障 pk 不超过 ll 范围
//这部分优化可以自行选择
}
return res;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
S=sqrt(n);
Euler_S();
for(ll l=1,r,v;l<=n;l=r+1){
r=n/(v=n/l);
if(v<=S)id1[v]=++tot;
else id2[n/v]=++tot;//两种分开存储
val[tot]=v;
v%=P;
g[tot]=v*(v+1)/2%P-1;//别忘了初始值没有包括 1
}
for(int j=1;j<=cnt;j++){
for(int i=1;i<=tot&&p[j]<=val[i]/p[j];i++){
int id=Get(val[i]/p[j]);
g[i]=(g[i]-p[j]*(g[id]-sum[j-1]))%P;//直接用前缀和代替 g 数组
}
}
cout<<(SumF(n,0)+1+P)%P;//记得单独加上 1 的贡献
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律