博客
关于我
Min_25筛
阅读量:285 次
发布时间:2019-03-03

本文共 3894 字,大约阅读时间需要 12 分钟。

以前多次学习 Min_25筛,却一直一直不能透彻理解他

这挺让我沮丧的,本来不想写这篇博文,现在看来不写不行


Min_25筛

Min_25筛 是用来求解积性函数前缀和的快速筛法

但他对积性函数有一定要求,要求 f ( x ) , x ∈ P r i m e f(x),x\in Prime f(x),xPrime 是一个简单多项式,且 f ( x k ) , x ∈ P r i m e f(x^k),x\in Prime f(xk),xPrime 可以快速计算

Min_25筛的算法过程分为两步,先求质数的 f ( x ) f(x) f(x) 的和,再求 f ( x ) f(x) f(x) 的和也就是答案。


求质数的 f f f 的和

g ( x ) g(x) g(x) 表示把 x x x 当作质数时计算 f ( x ) f(x) f(x) 得到的结果。

G ( i , j ) , i = ⌊ n / d ⌋ G(i,j),i=\lfloor n/d\rfloor G(i,j),i=n/d 表示在前 i i i 个数中,没有被前 j j j 个质数筛掉数的 g g g 的和。

那么一开始 G ( i , 0 ) = ∑ k = 2 i g ( k ) G(i,0)=\sum_{k=2}^ig(k) G(i,0)=k=2ig(k) 。我们要保留的 g g g 都是质数的 g g g ,就要把合数的 g g g 筛走。

从小到大枚举质数 P j P_j Pj ,把最小质因子恰好为 P j P_j Pj 的那些合数的 g g g G G G 中去掉,枚举 ≥ P j 2 \ge P_j^2 Pj2 i i i G ( i , j ) G(i,j) G(i,j) 要减去 G ′ ( ⌊ i / P j ⌋ , j − 1 ) − ∑ k ≤ j − 1 g ( P k × P j ) G'(\lfloor i/P_j\rfloor,j-1)-\sum_{k\le j-1}g(P_k\times P_j) G(i/Pj,j1)kj1g(Pk×Pj) G ′ G' G 就是 ∑ g ( i ⋅ P j ) \sum g(i\cdot P_j) g(iPj)

最后的 G ( n , ∣ P ∣ ) G(n,|P|) G(n,P) 就是质数的 f f f 的和。


f f f 的和

F ( i , j ) , i = ⌊ n / d ⌋ F(i,j),i=\lfloor n/d\rfloor F(i,j),i=n/d 表示表示在前 i i i 个数中,最小质因子 ≥ P j \ge P_j Pj f f f 的和。 F ( n , ∣ P ∣ + 1 ) = 0 F(n,|P|+1)=0 F(n,P+1)=0

因为已经求了 G G G 的答案,现在只需要把合数的 f f f 加上去即可。从大到小枚举 P j P_j Pj ,把最小质因子恰好为 P j P_j Pj 的那些合数的 f f f 加到 F F F 中去,枚举 ≥ P j 2 \ge P_j^2 Pj2 i i i ,再枚举 P j e + 1 ≤ i P_j^{e+1}\le i Pje+1i e e e ,也就是那些合数中 P j P_j Pj 的指数。 F ( i , k ) , k ≤ j F(i,k),k\le j F(i,k),kj, 要加上 f ( P j e ) ⋅ F ( ⌊ i / P j e ⌋ , j + 1 ) + f ( P j e + 1 ) f(P_j^e)\cdot F(\lfloor i/P_j^e\rfloor,j+1)+f(P_j^{e+1}) f(Pje)F(i/Pje,j+1)+f(Pje+1)

f f f 的和就是 F ( n , 1 ) + 1 F(n,1)+1 F(n,1)+1


总结

G ( i , j ) = { G ( i , j − 1 ) P j 2 > i G ( i , j − 1 ) − G ′ ( ⌊ i / P j ⌋ , j − 1 ) + ∑ k ≤ j − 1 g ( P k × P j ) P j 2 ≤ i G(i,j)= \begin{cases} G(i,j-1) &P_j^2> i \\ G(i,j-1)-G'(\lfloor i/P_j\rfloor,j-1)+\sum_{k\le j-1}g(P_k\times P_j) &P_j^2\le i \\ \end{cases} G(i,j)={

G(i,j1)G(i,j1)G(i/Pj,j1)+kj1g(Pk×Pj)Pj2>iPj2i

F ( n , j ) = ∑ i ≥ j f ( P i ) + ∑ k ≥ j ∑ e f ( P k e ) F ( n / P k e , k + 1 ) + f ( P k e + 1 ) F(n,j)=\sum_{i\ge j}f(P_i)+\sum_{k\ge j}\sum_{e}f(P_k^e)F(n/{P_k^e},k+1)+f(P_k^{e+1}) \\ F(n,j)=ijf(Pi)+kjef(Pke)F(n/Pke,k+1)+f(Pke+1)


洛谷的板题

#include 
#define N 1000006using namespace std;typedef long long ll;const ll mod=1e9+7,inv2=5e8+4,inv3=(mod+1)/3;ll pri[N],num,sp1[N],sp2[N];ll n,sqr,tot,g[N],gg[N],w[N],id1[N],id2[N];bool tag[N];void mo(ll &x){ x=(x%mod+mod)%mod; }ll find_pos(ll x){ return x<=sqr?id1[x]:id2[n/x]; }void init(ll n){ tag[1]=1; for(ll i=1;i<=n;i++){ if(!tag[i]){ pri[++num]=i; sp1[num]=(sp1[num-1]+i)%mod; sp2[num]=(sp2[num-1]+1ll*i*i)%mod; } for(ll j=1;j<=num&&pri[j]*i<=n;j++){ tag[i*pri[j]]=1; if(i%pri[j]==0) break; } }}ll S(ll x,ll y){ // 前 x 个数中,最小质因数大于 pri_y 的数的函数和 if(pri[y]>=x) return 0; ll k=find_pos(x); ll res=(gg[k]-g[k]+mod-(sp2[y]-sp1[y])+mod)%mod,pe,xx;// cout<
<<'\n'; for(ll i=y+1;i<=num&&pri[i]*pri[i]<=x;i++){ xx=pe=pri[i]; for(ll e=1;pe<=x;pe=pe*pri[i],xx=pe%mod,e++) (res+=xx*(xx-1)%mod*(S(x/pe,i)+(e!=1))%mod)%=mod; //把合法的合数加回来 }// cout<
<<'\n'; return res;}int main(){ cin>>n; sqr=sqrt(n); init(sqr); for(ll l=1,r;l<=n;l=r+1){ r=n/(n/l); w[++tot]=n/l; g[tot]=w[tot]%mod; gg[tot]=g[tot]*(g[tot]+1)/2%mod*(2*g[tot]+1)%mod*inv3%mod; g[tot]=g[tot]*(g[tot]+1)/2%mod; g[tot]--,gg[tot]--; if(w[tot]<=sqr) id1[w[tot]]=tot; else id2[n/w[tot]]=tot; } //初始化 现在的 G 数组表示没有被前 0 个质数筛掉的 g 的和 ll k; for(ll i=1;i<=num;i++){ //筛 for(ll j=1;j<=tot&&pri[i]*pri[i]<=w[j];j++){ k=find_pos(w[j]/pri[i]); mo(g[j]-=g[k]*pri[i]%mod-sp1[i-1]*pri[i]%mod); mo(gg[j]-=pri[i]*pri[i]%mod*(gg[k]-sp2[i-1]+mod)%mod); } // cout<
<<'\n'; } cout<<(S(n,0)+1)%mod;}

【LibreOJ #6053】

【JZOJ 5683】【GDSOI2018模拟4.22】
【51NOD 1847】
【51NOD 1965】

我是在 学的

转载地址:http://pohl.baihongyu.com/

你可能感兴趣的文章
[Golang]golang中自动锁的实现
查看>>
用float/double作为中转类型的“雷区”
查看>>
golang中interface的一些语法缺陷的改进
查看>>
vue-router路由 学习笔记
查看>>
数据结构与算法之栈
查看>>
【数据库】第七章课后题
查看>>
第四章 串、数组和广义表 —— BF算法和KMP算法
查看>>
[选拔赛1]花园(矩阵快速幂),JM的月亮神树(最短路),保护出题人(斜率优化)
查看>>
DLA:一种深度网络特征融合方法
查看>>
leetcode114(二叉树展开为链表)
查看>>
java —— this 关键字
查看>>
java —— static 关键字
查看>>
Firefox 69 已可在 Fedora 中获取 | Linux 中国
查看>>
在 Python 调试过程中设置不中断的断点 | Linux 中国
查看>>
AI 系统向自动化编码迈进 | Linux 中国
查看>>
使用 Jupyter Notebooks 构建一个远程管理控制台 | Linux 中国
查看>>
使用开源可视化工具来理解你的 Python 代码 | Linux 中国
查看>>
【2021 ECUG Con】聚势而来,与你相约花开时
查看>>
硬核观察 | 有人在比特币骗局中损失了 10 个比特币
查看>>
在 Ubuntu 17.10 上安装 AWFFull Web 服务器日志分析应用程序 | Linux 中国
查看>>