筛法

news/2025/1/15 18:44:59/文章来源:https://www.cnblogs.com/qwq-123/p/18673599

杜教筛

你现在需要求一个函数 \(f(n)\) 的前缀和 \(F(n)=\sum_{i=1}^n f(i)\) ,然后经过一些机缘巧合,你发现这个 \(f(n)\) 有以下性质:

  • 存在一个积性函数 \(g(n)\) ,可以快速计算其前缀和 \(G(n)=\sum_{i=1}^n g(i)\)
  • 数论函数 \(f\)\(g\) 的狄利克雷卷积 \(h=f*g\) 的前缀和 \(H(n)=\sum_{i=1}^n h(i)\) 可以快速计算。

这样有以下式子:

\[\begin{aligned} \sum_{i=1}^nf*g&=\sum_{i=1}^n \sum_{d|i}f(d)g(\frac i d)\\ &=\sum_{d=1}^n g(d)\sum_{k=1}^{\frac n d} f(k)\\ &=\sum_{i=1}^n f(i)+\sum_{d=2}^n G(d)\sum_{k=1}^{\frac n d} f(k)\\ \end{aligned} \]

所以有:

\[\begin{aligned} F(n)=H(n)-\sum_{d=2}^n G(d)F(\lfloor \frac n d\rfloor) \end{aligned} \]

代码:(此处 \(f(n)=n\varphi(n)\),则 \(g(n)=n,h(n)=n^2\)


ll getG(ll n){if(n<=N)return sg[n];if(G.count(n))return G[n];//注意取模问题!!ll ans=n%mod*((n+1)%mod)%mod*((n+n+1)%mod)%mod*inv6%mod;for(ll l=2,r;l<=n;l=r+1){ll x=n/l;r=n/x;ans=(ans-(r-l+1)%mod*((l+r)%mod)%mod*getG(x)%mod*inv2%mod+mod)%mod;}return G[n]=ans;
}

Powerful Number 筛

你现在需要求一个积性函数 \(f(n)\) 的前缀和 \(F(n)=\sum_{i=1}^n f(i)\) ,然后经过一些机缘巧合,你发现这个 \(f(n)\) 有以下性质:

  • 存在一个积性函数 \(g(n)\) ,可以快速计算其前缀和 \(G(n)=\sum_{i=1}^n g(i)\)
  • 对于质数 \(p\),有 \(g(p)=f(p)\)

与杜教筛相比,你不需要找到 \(f*g\) 有什么实际含义,只需要找到一个 \(f\) 的近似函数 \(g\) ,使他两在质数部分取值相同即可。

由于 \(f,g\) 都是积性函数,所以我们可以假设有一个积性函数 \(h\) ,使其满足 \(h*g=f\) ,所以有:

\[\begin{aligned} F(n)=\sum_{i=1}^ng*h&=\sum_{i=1}^n \sum_{d|i}h(d)g(\frac i d)\\ &=\sum_{d=1}^n h(d)\sum_{k=1}^{\frac n d} g(k)\\ &=\sum_{d=1}^n h(d)G(\lfloor \frac n d\rfloor) \end{aligned} \]

然后有性质:

  • 对于任意一个质数 \(p\),有 \(f(p)=g(p)h(1)+g(1)h(p)=g(p)+h(p)=f(p)+h(p)\),所以 \(h(p)=0\),由积性函数的定义,那么对于任意一个非 PN 数,其 \(h(n)=0\)。( PN 数 \(x\) 就是不存在一个 \(x\) 的质因数 \(p\),使 \(x\bmod p^2\neq 0\)
  • \(n\) 以内的PN数至多 \(O(\sqrt n)\) 个,所以上面的式子在能算 \(h(p^k)(k\ge 2)\) 的情况下就可以只算 \(O(\sqrt n)\) 次就能得到 \(F(n)\) 的值。

下面就是考虑求 \(h(p^k)\) ,根据:

\[f(p^k)=\sum_{i=0}^k g(p^i)h(p^{k-i}) \]

所以:

\[h(p^k)=f(p^k)-\sum_{i=1}^k g(p^i)h(p^{k-i}) \]

那么 \(h(p^k)\) 就可以递推出来,整个复杂度大概是 \(O(\sqrt n\log n)\) 的规模。

代码(此时 \(f(p^k)=p^k(p^k-1)\),那么 \(g(n)=n\varphi(n)\)):

void sous(int now,ll x,ll valh){//now表示第几个质数,x表示当前的PN数,h因为是积性函数所以valh为几个val相乘。if(now>top||x*p[now]>n||x*p[now]*p[now]>n)return;sous(now+1,x,valh);x*=p[now]*p[now];vector<ll> H;H.push_back(1);H.push_back(0);ll cf=p[now]*p[now]%mod;for(int k=2;x<=n;++k,x*=p[now],cf=cf*p[now]%mod){ll val=cf*(cf-1)%mod,cf2=1;for(int t=1;t<=k;++t,cf2=cf2*p[now]%mod){val=(val-cf2*cf2%mod*p[now]%mod*(p[now]-1)%mod*H[k-t]%mod+mod)%mod;}H.push_back(val);ans=(ans+valh*val%mod*getG(n/x)%mod)%mod;sous(now+1,x,valh*val%mod);}
}
ans=getG(n)

此外,在某些情况下,我们是可以知道 \(h(p^k)\) 具体的值的,例如上面的情况,有:

\[\begin{aligned} p^k(p^k-1)&=\sum_{i=2}^kp^{i+i-1}(p-1)h(p^{k-i})+h(p^k)+h(p^{k-1})p(p-1)\\ p^{k-1}(p^{k-1}-1)&=\sum_{i=1}^{k-1}p^{i+i-1}(p-1)h(p^{k-1-i})+h(p^{k-1})\\ p^{k+1}(p^{k-1}-1)&=\sum_{i=2}^{k}p^{i+i-1}(p-1)h(p^{k-i})+p^2h(p^{k-1})\\ \end{aligned} \]

所以有 \(p^k(p^k-1)-p^{k+1}(p^{k-1}-1)=p^k(p^k-1-p^k+p)=h(p^k)-ph(p^{k-1})\)

\(\dfrac{h(p^k)}{p^k}-\dfrac{h(p^{k-1})}{p^{k-1}}=p-1\),所以 \(h(p^k)=(k-1)(p-1)p^k\)

上列推导如此复杂的原因是 \(\varphi(p^0)\neq p^{-1}(p-1)\),所以 \(\sum_{i=0}^kp^i\varphi(p^i)\neq \sum_{i=0}^kp^{i+i-1}(p-1)\),不然应该可以直接式子整体代换就可以了。

Min_25 筛

Min_25筛相比上面两种筛法,灵活性会高很多,本人感觉Min25筛更像是一种思想。

现在考虑你要求积性函数 \(f(n)\) 的前缀和 \(F(n)=\sum_{i=1}^n f(i)\)

我们记 \(S(n,j)\) 表示:\(\sum_{x} f(x)\),其中 \(x\) 满足:\(1\le x\le n\)\(x\) 的最小质因子 \(>p_j\)(表示第 \(j\) 大的质数)。

最终 \(F(n)=S(n,0)\) ,现在考虑求 \(S(n,j)\) ,就要对满足条件的 \(x\) 进行统计。

我们将这样的 \(x\) 分成质数和合数:

  • 考虑质数部分,现在我们引入 \(g(n,j)\) 表示:\(\sum_{x} f(x)\) ,其中 \(x\) 满足:\(1\le x\le n\)\(x\) 要么是质数,要么其最小质因子 \(>p_j\)

    那么这部分就是 \(g(n,\infty)\)

  • 考虑合数部分。

    因为合数部分的最小质因子都是 \(>p_j\),我们就枚举最小质数 \(p_k\) 的几次方 \(p_k^e\) ,由于 \(f(x)\) 是积性函数,那么这部分就是 \(f(p_k^e)\left(S(\dfrac{n}{p_k^e},k)+[e>1]\right)\)

    注意上式要有值当且仅当 \(p_k^2\le n\) ,这样我们就可以极大的减少枚举的复杂度。

然后就有证明,假如如果我们已经求出 \(g(n,\infty)\) ,那么这部分的时间复杂度就是 \(O(\frac{n^{0.75}}{\log n})\)

现在考虑求出 \(g(n,j)\)

为了方便计算,我们并不直接算出 \(\sum_x f(x)\),而是将 \(f(x)\) 拆成一些完全积性函数 \(g_1(n),g_2(n)\) 的和,而且由于我们用到的只有 \(g(n,\infty)\),所以我们只需要保证对于任意质数 \(p,f(p)=g_1(p)+g_2(p)\) 就可以了。

考虑计算 \(g_1(n,j)\)

  • \(p_j^2>n\) 时, \(g_1(n,j)=g_1(n,j-1)\) 是比较显然的。

  • 否则,相比 \(g_1(n,j-1)\),我们需要排除包含 \(p_j\) 为质因子的数,由于完全积性函数的性质,这部分就是 \(g_1(p_j)g_1(\frac{n}{p_j},j-1)\)

    但需要注意 \(g_1(n,j)\) 中包含了质数,所以需要减掉 \(1\sim j-1\) 中质数的情况。

所以有转移:

\[g_1(n,j)= \begin{cases} g_1(n,j-1)&(p_j^2>n)\\ g_1(n,j-1)-g_1(p_j)\left(g_1(\frac{n}{p_j},j-1)-\sum_{i=1}^{j-1}g_1(p_i)\right) &(p_j^2\le n) \end{cases} \]

但由于 \(n\) 巨大,所以想要把所有 \(g_1(n,j)\) 都求出来是不现实的。

但有一个很好的性质:所有 \(g(n,j)\)\(n\) 都是最初始的 \(n\) 除上一个整数,即 \(\lfloor \frac{n}{x}\rfloor\) ,那么这样要处理的 \(g_1(n,j)\) 的总复杂度被证明是 \(O(n^{1-\epsilon})\)

例:

ll getS(ll n,int j){if(n<p[j])return 0;int id=q[n];ll val=((ll)g2[id]-g1[id]-(sp2[j]-sp1[j])+mod+mod)%mod;for(int i=j+1;i<=top&&p[i]*p[i]<=n;++i){for(ll e=p[i];e<=n;e*=p[i])val=(val+e%mod*(e%mod-1+mod)%mod*(getS(n/e,i)+(ll)(e!=p[i])))%mod;}return val;
}int main(){for(ll l=1,r;l<=n;l=r+1){ll x=n/l;r=n/x,val[q[x]=++m]=x;x%=mod;//注意这里要把1的贡献排除掉g1[m]=((1+x)*x%mod*inv2%mod-1+mod)%mod;g2[m]=(x*(x+1)%mod*(x+x+1)%mod*inv6%mod-1+mod)%mod;}for(int i=1;i<=top;++i){for(int j=1;j<=m&&p[i]*p[i]<=val[j];++j){g1[j]=(g1[j]-p[i]*(g1[q[val[j]/p[i]]]-sp1[i-1]+mod)%mod+mod)%mod;g2[j]=(g2[j]-p[i]*p[i]%mod*(g2[q[val[j]/p[i]]]-sp2[i-1]+mod)%mod+mod)%mod;}}printf("%lld\n",(getS(n,0)+1)%mod);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/869732.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1.15

尽力了,之前的粗心导致现在要改很多以前的坑,明天再继续

中考英语优秀范文-热点话题-传统文化-006 Welcome to Chinese Summer Camp 欢迎参加中国夏令营

1 写作要求 假定你是李华,你校今年暑假将为外国学生举办一场汉语夏令营活动(Chinese Summer Camp)。请你根据下面海报的内容,用英语给你的笔友David写一封电子邮件,介绍本次活动并邀请他参加。词数80左右。 Welcome to Chinese Summer Camp Time:July 18th—July 28th, 2…

机器人

本文来自博客园,作者:Traktorea,转载请注明原文链接:https://www.cnblogs.com/kdsmyhome/p/18673586

使用Nginx实现前端映射到公网IP后端内网不映射公网.250115

一、场景: 系统移动端需要映射到公网,但是后端地址不能映射出去 qbpm.xxxx.cn 系统解析内网IP qmbpm.xxxx.cn 移动端解析公网IP 二、思路: 移动端前端公网端口放出80 443端口 移动端后端映射到内网后端地址qbpm.xxxx.cn:8443 三、解决方法: vim nginx.confserver {listen 8…

Qml 中实现任意角为圆角的矩形

在 Qml 中,矩形(Rectangle)是最常用的元素之一。 然而,标准的矩形元素仅允许设置统一的圆角半径。 在实际开发中,我们经常需要更灵活的圆角设置,例如只对某些角进行圆角处理,或者设置不同角的圆角半径。 本文将介绍如何通过自定义 Qml 元素实现一个任意角可为圆角的矩形…

【附源码】JAVA在线投票系统源码+SpringBoot+VUE+前后端分离

学弟,学妹好,我是爱学习的学姐,今天带来一款优秀的项目:在线投票系统源码 。 本文介绍了系统功能与部署安装步骤,如果您有任何问题,也请联系学姐,偶现在是经验丰富的程序员! 一. 系统演示 系统测试截图系统视频演示https://githubs.xyz/show/340.mp4二. 系统概述【 系统…

Python Playwright学习笔记(一)

一、简介 1.1Playwright 是什么? 它是微软在 2020 年初开源的新一代自动化测试工具,其功能和 selenium 类似,都可以驱动浏览器进行各种自动化操作。 1.2、特点是什么支持当前所有的主流浏览器,包括 chrome、edge、firefox、safari; 支持跨平台多语言:支持Windows、Linux、…

智能驾驶数据采集回注测评工具 - ARS

在数据驱动智能驾驶的时代背景下,开发者们总结了一条适用于智能驾驶的数据闭环开发流程,这条开发线路大致包括实车数据采集->数据存储->数据处理->数据分析->数据标注->模型训练->仿真测试->实车测试->部署发布等关键环节,通过不断开发迭代,逐步完…

2025.1.15 学习

2025.1.15 学习 api开放平台 我们希望在后端使用Http请求调用接口,应该怎么做呢 可以用Hutool工具库中的Http请求工具类,使用如下: public class ApiClient {public String getNameByGet(String name){HashMap<String, Object> paramMap = new HashMap<>();para…

2024龙信年终技术考核

1. 分析手机备份文件,该机主的QQ号为?(标准格式:123) 看了下,备份里没有QQ,但是有微信,所以应该是微信绑定的QQ号(早期微信推广时可以用QQ直接注册登录)经过测试,对应的是这个结果为1203494553 2. 分析手机备份文件,该机主的微信号为?(标准格式:abcdefg)结果为…

Dex文件结构】ReadDex解析器实现

# APP加壳脱壳 # DEX文件结构 近期学习DEX文件结构为学习APP加壳脱壳打基础,自实现了一个简易的DEX解析器加深理解。DEX文件结构整体看不复杂,深究时发现DexCLassDef结构非常复杂,编码的数据结构,嵌套和指向关系。本文作为近期学习的一个阶段总结以及知识分享,后期再完…

记录---浏览器多窗口通信有效实践总结

🧑‍💻 写在开头 点赞 + 收藏 === 学会🤣🤣🤣如何跨越不同窗口通信 在现代 Web 开发中,多个窗口或标签页之间的通信成为了越来越常见的需求,尤其是在应用需要同步数据、共享状态或进行实时更新的场景中。不同窗口间的通信方式有很多种,选择合适的方式可以大大提高…