博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Min_25筛学习笔记
阅读量:6956 次
发布时间:2019-06-27

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

感觉好好用啊

Luogu上的杜教筛模版题一发 Min_25抢到了 rank1

$ Updated \ on 11.29 $被 踩爆啦


 

前言

$ Min$_$25$筛可以求积性函数的前缀和

要求$ f(p_i)为一个多项式,f(p_i^{k_i})可以快速计算$

以下部分暂时忽略$ 1$,即只考虑最小质因子$ \geq 2$的那些数

 


 

先考虑素数贡献

我们定义$ sp(n)$表示$\sum\limits_{i=1}^n f(p_i)$即前$ n$个素数的积性函数和

这里我们先假设$ f$对于质数的计算是完全积性函数

$ P_i$表示线筛求出的第$ i$小的质数

令$ g(n,i)$表示$ \sum\limits_{j=2}^n [j的最小质因数>P_i或j是质数]f(j)$

在这里$ f(j)$表示假设$ j$是质数,以质数方式带入函数计算的结果

由于合数会被筛掉因而不会影响答案

考虑怎么计算$ g(n,i)$

类似线性筛的方式每次筛掉一批合数

如果$P_i^2>n$则有$ g(n,i)=g(n,i-1)$

因为第$ i$个质数能筛掉的最小合数是$ P_i^2$

因此筛质数只需要筛到$ \sqrt n$即可

如果$ P_i^2<=n$有$ g(n,i)=g(n,i-1)-f(P_i)*(\ g( \frac{n}{P_i},i-1)-sp_{i-1}\ )$

原理是假设$ P_i$是一个质因数,它能产生的合数贡献是$ f(P_i)*g( \frac{n}{P_i} ,i-1)$

但是由于$ P_i$不一定是最小质因数,还要加回多减的小质数即$ sp_{i-1}$

由于满足$ f$是完全积性函数,上面部分还算挺清真的

我们需要求的只是$ g(x,INF)$

注意我们发现我们需要求的$ g(x,INF)$只需要满足存在$ d$使得$ x=\frac{n}{d} $即可

可以提前整数分块这样只需要计算$ \sqrt n$数量级的$ g(x,INF)$即可

可以通过滚动数组递推的方式完成这一部分

 


 我们令$ S(n,m)$表示$ \sum\limits_{i=2}^n[i的最小质因数 \geq P_m]f(i)$

显然我们要求的是$ S(n,1)$

递归求解

贡献分两步统计:

质数贡献:$ g(n,INF)-sp(m-1)$

即去掉较小的质数以外其他质数都会被计算到

合数贡献:$ \sum\limits_{k=m}^{P_k^2<=n}\sum\limits_{e=1}^{P_k^{e+1}<=n}f(P_k^e)S(\frac{n}{P_k^e},k+1)+f(P_k^{e+1})$

即枚举当前选择的最小质因数以及数量转移,同时计算只选择多于两个当前因数即不往后转移的合数情况

这样直接转移就好了


栗子:筛$ \sum\limits_{i=1}^n \phi(i)$

发现$ phi(P_i)=P_i-1$即对于质数的计算不是一个完全积性函数

这时候需要拆开计算

令$ g(P_i)=P_i$,$ h(P_i)=1$

这样分成两个完全积性函数,分别筛质数求值然后相减即可

推$ S(n,m)$的时候不会有影响

筛$ \sum\limits_{i=1}^n \mu(i)$也没有本质区别

传送门:

$ my \ code:$

#include
#include
#include
#include
#include
#include
#include
#define file(x)freopen(x".in","r",stdin);freopen(x".out","w",stdout)#define rt register unsigned#define l putchar('\n')#define ll long long#define r read()using namespace std;inline ll read(){ ll x = 0; char zf = 1; char ch = getchar(); while (ch != '-' && !isdigit(ch)) ch = getchar(); if (ch == '-') zf = -1, ch = getchar(); while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar(); return x * zf;}void write(ll y){ if(y<0)putchar('-'),y=-y;if(y>9)write(y/10);putchar(y%10+48);}void writeln(const ll y){write(y);putchar('\n');}int i,j,k,m,n,x,y,z,cnt;ll sp[100010],g[100010];int h[100010],ss[100010];bool pri[100010];int id1[100010],id2[100010],q[100010],t,sz;void init(){ sz=sqrt(n); for(rt i=2;i<=sz;i++){ if(!pri[i])ss[++cnt]=i,sp[cnt]=sp[cnt-1]+i; for(rt j=1;j<=cnt&&i*ss[j]<=sz;j++){ pri[i*ss[j]]=1; if(i%ss[j]==0)break; } } for(rt i=1;i<=n;){ const unsigned v=n/i;unsigned R=n/v; q[++t]=v;if(v<=sz)id1[v]=t;else id2[n/v]=t; g[t]=(ll)v*(v+1)/2-1; h[t]=v-1;i=R+1; }}int id(int x){ if(x<=sz)return id1[x]; return id2[n/x];}ll S(int n,int m){ if(n<=1||ss[m]>n)return 0; ll ret=g[id(n)]-sp[m-1]+m-1;//cout<
<<' '<
<
n)return 0; int ret=h[id(n)]+(m-1);//cout<
<<' '<
<

 

转载于:https://www.cnblogs.com/DreamlessDreams/p/9997874.html

你可能感兴趣的文章
reverse() ; sort() ; sorted()
查看>>
Finalize/Dispose资源清理模式
查看>>
封装dialog弹窗
查看>>
使用synchronized(非this对象)同步代码块解决脏读问题
查看>>
Oracle中使用批处理文件批量建表
查看>>
Intel笔记本低压版CPU性能对比分析
查看>>
Gephi可视化(二)——Gephi Toolkit叫板Prefuse
查看>>
Fiddler环境配置教程
查看>>
第二阶段冲刺报告
查看>>
Vue.js 系列教程 5:动画
查看>>
WinForm 使用 HttpUtility
查看>>
Zabbix QQ报警配置
查看>>
2016.8.7 UnicodeEncodeError 同时遍历多个list
查看>>
基础 网络架构 网络硬件名词 网络通信协议
查看>>
sqlite
查看>>
关于Retinex图像增强算法的一些新学习。
查看>>
一道容易栽坑的有趣的面试题(关于js,定时器,闭包等)
查看>>
正则表达式,时间戳和日期互相转换
查看>>
mysql复制(高可用架构方案的基础)
查看>>
搭建自己的OwnCloud私有云
查看>>