问题描述

  快速求素数处点值比较好求积性函数前缀和

  

大致过程

  Step1、求出一定范围内的素数处点值之和(\(g\))

  Step2、利用上面的\(g\)求出一个\(f\)然后用\(f\)求出前缀和

  

具体过程

  (这里约定一下,在下面的内容中用\(p\)表示一个素数,用\(P_i\)表示素数列表中的第\(i\)项)

  这里以求\(\sum \phi(i)\)为例

  首先对于素数\(p\)来说,\(\phi(p)=p-1\)的,因此我们可以快速求出素数处点值的和\(\sum \phi(p)=\sum p - \sum 1\)

  这个时候我们定义
\[
\begin{aligned}
g_{i,j}&=\sum\limits_{k=2}^{i}[k与P_1、P_2、P_3...P_j互质或者就是其中的某个素数]k\\
&=\sum\limits_{k=2}^{i}[k是P_j的素数\ 或\ k的最小质因子>P_j]k\\
\end{aligned}
\]
  初始化\(g_{i,0}=\sum\limits_{k=2}^{i} k\)

  有了这个东西的话我们就可以比较快速的知道某一个范围内的素数处点值的函数值和了

  现在考虑\(g_{i,j}\)怎么求,我们考虑从\(g_{i,j-1}\)推到\(g_{i,j}\)

  (这里的大体思想其实和。。之前在博客里面写到的某道题pxp。。差不多,或者说pxp其实就是洲阁筛的前半部分)

​  

  将具体的含义列出来,我们要做的就是从
\[
满足k<=P_{j-1}的素数\ 或\ k的最小质因子>P_{j-1}的k的和
\]
  推到
\[
满足k<=P_j的素数\ 或\ k的最小质因子>P_j的k的和
\]
  看一下我们要修改的部分,对于前半部分来说应该是加上一个\(P_j\)(如果在范围内的话),对于后半部分来说应该是减去一些数(不满足第二个条件),这些数满足
\[
x=P_j*(一个y满足最小质因子>P_j,并且范围在[P_j,\lfloor\frac{i}{P_j}\rfloor]的数)
\]
  于是乎我们非常愉快地发现后面那个括号里面的那一堆东西的和可以用回\(g\)来容斥一下表示!
\[
\sum y=g_{\lfloor\frac{i}{P_j}\rfloor,j-1}-g_{P_j-1,j-1}
\]
  然后我们就可以由\(g_{i,j-1}\)推到\(g_{i,j}\)啦
\[
g_{i,j}=g_{i,j-1}-P_j(g_{\lfloor\frac{i}{P_j}\rfloor,j-1}-g_{P_j-1,j-1})
\]
​  然而对于不同的积性函数来说,第一步的求法会有一定的差异,也许会有更加简单的求法,反正就是要求出一个函数能够快捷方便滴得到某一个范围内的素数处点值的和就好了

  

  如果一定要写一个通式的话其实就是:
\[
g_{i,j}=g_{i,j-1}-F(P_j)(g_{\lfloor\frac{i}{P_j}\rfloor,j-1}-g_{P_j-1,j-1})
\]
  其中满足\(F\)是一个完全积性函数(因为把\(P_j\)提出来那步需要用到完全积性函数的性质,你并不能保证后面的那堆东西一定和\(P_j\)互质)

  然后\(F\)的话具体看最开始给的要求前缀和的函数在素数处的点值的表达式具体是啥而定,比如在这个例子里面就是\(F(x)=x\)

​   
  
  

  接下来是用这个\(g\)来求\(h\)
\[
h_{i,j}=\sum\limits_{k=2}^{i}[k最小质因子>=P_j]\phi(k)
\]
​  (如果是别的函数的话就换一下后面的\(\phi(k)\)就可以了)

  考虑这样一种枚举方式:

  每一个数我们都可以拆成
\[
(最小质因子)^q*一些别的东西(可以是1)
\]
​  所以我们可以将上面的表达式通过枚举素数以及次方的方式写成这样:
\[
h_{i,j}=\sum_{q}\phi(P_j^q)\cdot h_{\lfloor \frac{i}{P_j^q}\rfloor,j+1}
\]
  然后就可以推\(h_{i,j}\)啦

​  然而。。。直接搞会比较麻烦。。因为这里为了保证复杂度还是需要上面提到的\(i>=P_j^2\)的优化,但是这里没有那么简单,而是需要打上标记

  所以这里写上另一种方式(貌似是min_25筛来着)
\[
h_{i,j}=\sum_{P_k>=P_j}\sum_{q>=1,P_k^q<=i}\phi(P_k^q)\cdot(h_{\lfloor \frac{i}{P_k^q}\rfloor,j+1}+1)
\]
  后面那里要\(+1\)是因为要把\(\phi(P_k^q)\)的部分也算上(否则都是\(一些别的东西\phi(P_k^q*一些别的东西)\))

  然后直接大力搜索就可以了

  边界条件:\(i<=1\)的时候返回\(0\)

  有趣的是,并不需要记忆化ovo

  因为可以说明\(h\)是不会被重复调用的%%%

  然后最后的答案就是\(h_{n,1}+\phi(1)\)啦

  

总的来说

  额其实就是
\[
\begin{aligned}
g_{i,j}&=g_{i,j-1}-F(P_j)(g_{\lfloor\frac{i}{P_j}\rfloor,j-1}-g_{P_j-1,j-1})\\
\\
h_{i,j}&=\sum_{P_k>=P_j}\sum_{q>=1,P_k^q<=n}f(P_k^q)\cdot h_{\lfloor \frac{i}{P_k^q}\rfloor,j+1}
\end{aligned}
\]
​  然后\(F\)是完全积性函数,\(f\)是题目给的是一个积性函数,\(F\)是根据\(f\)在素数处点值的表达式构造的

  大概是这样嗯ovo

  哦然后时间复杂度是\(O(\frac{n^{\frac{3}{4}}}{logn})\)的至于证明的话。。不会qwq

  虽然说思路真的巨无敌绕不过弄懂了的话还是比较好理解的ovo(假装这两句话一点都不矛盾)

  

实现问题

  关于实现的话有这样几个比较重要的点单独拿出来说一下

  

  1.Step1中,关于\(g_{i,j}\)的求解:

  题目中的\(n\)往往很大,\(i\)直接这么枚举的话直接就愉快爆炸了

  这里我们可以发现一个性质,就是我们其实只用关注第一维的\(i\)满足\(i \in \{\lfloor \frac{n}{x} \rfloor|x \in [1,n]\}\)的\(g_{i...}\)值

  我们将这个集合记为\(S\),那么是有\(|S|=2\sqrt n\)的,在具体实现的时候,我们可以先离散化一下,需要调用的时候再映射回去就好了

  为什么我们可以这么做呢?看回递推式中我们需要的\(g\)的第一维,前一部分是\(\lfloor \frac{i}{P_j} \rfloor\),这是\(\in S\)的,后一部分是\(P_j-1\),因为\(P_j\)我们限制是\(< \sqrt n\)的,所以\(P_j-1\in S\),所以只有\(i\in S\)的\(g_{i,...}\)才是我们实际需要算的值

  

  2.Step2中,关于\(h_{i,j}\)的求解:

​  同样的,如果第一维直接枚举\(n\)的话简直炸成烟花

  这里观察一下当\(i<P_j\)的情况,会发现当\(i<P_j^2\)的时候,能算进来的只有\(且>=P_j且<=i\)的质数处的函数值,所以这一部分的和可以直接用\(g_{i,max+1}-g_{P_j-1,max+1}\)表示,其中\(max\)是素数列表的长度

  所以枚举的时候只枚举到\(P_j^2<=i\),然后最后判断一下如果存在\(i<P_j^2\)这种情况的话,就把后面整段的值一起加进返回值里,也就是直接加上\(g_{i,max+1}-g_{P_j-1,max+1}\)

  
  3.关于数组大小的问题。。因为关键位置的集合\(S\)的大小是\(2\sqrt n\),所以相关数组要开\(2\sqrt n\)而不是\(\sqrt n\)

  

代码的话

  看这题好了 Portal -->【SPOJ】DIVCNTK

【learning】洲阁筛的更多相关文章

  1. 【Learning】积性函数前缀和——洲阁筛(min_25写法)

    问题描述 洲阁筛解决的问题主要是\(n\)范围较大的积性函数前缀和. ​ 已知一积性函数\(f(i)\),求\(\sum_{i=1}^nf(i)\). \(n\leq10^{12}\). 求解方法 如 ...

  2. 杜教筛进阶+洲阁筛讲解+SPOJ divcnt3

    Part 1:杜教筛进阶在了解了杜教筛基本应用,如$\sum_{i=1}^n\varphi(i)$的求法后,我们看一些杜教筛较难的应用.求$\sum_{i=1}^n\varphi(i)*i$考虑把它与 ...

  3. 【XSY3042】石像 拓扑排序 状压DP 洲阁筛

    题目大意 有 \(n\) 个整数 \(a_1,a_2,\ldots,a_n\),每个数的范围是 \([1,m]\).还有 \(k\) 个限制,每个限制 \(x_i,y_i\) 表示 \(a_{x_i} ...

  4. 洲阁筛 & min_25筛学习笔记

    洲阁筛 给定一个积性函数$F(n)$,求$\sum_{i = 1}^{n}F(n)$.并且$F(n)$满足在素数和素数次幂的时候易于计算. 显然有: $\sum_{i = 1}^{n} F(n) = ...

  5. 模板 - 洲阁筛 + min25筛

    好像在某些情况下杜教筛会遇到瓶颈,先看着.暑假学一些和队友交错的知识的同时开这个大坑.

  6. LOJ6053 简单的函数 【Min_25筛】【埃拉托斯特尼筛】

    先定义几个符号: []:若方括号内为一个值,则向下取整,否则为布尔判断 集合P:素数集合. 题目分析: 题目是一个积性函数.做法之一是洲阁筛,也可以采用Min_25筛. 对于一个可以进行Min_25筛 ...

  7. [NOI2016]循环之美(杜教筛)

    首先要求每个数互不相等,故有$x\perp y$. 可以发现$\frac{x}{y}$在$k$进制下为纯循环小数的充要条件为$x\cdot k^{len}\equiv x(mod\ y)$,即$y\p ...

  8. min25筛学习笔记

    min25筛简介:用来求积性函数F(x)前缀和的,复杂度O(n0.75/logn),大概能求n<=1010. 记一个数x的最小质因子为R(x),所以当x不为质数时,R(x)<=√x这是废话 ...

  9. min_25筛入门

    目录 1.什么是min_25筛 2.前置知识 2.1.数论函数 2.2.埃拉托色尼筛 2.3.欧拉筛 3.min_25筛 3.1.计算质数贡献 3.2.计算总贡献 3.3.实现 4.例题 4.1.[L ...

随机推荐

  1. JavaScript学习笔记(一)——JS速览

    第一章 JS速览 1 限制时间处理事件 <script> setTomeout(wakeUpUser,5000); function wakeUpUser() { alert(" ...

  2. mysql 5.5 zip配置安装

    1.解压2.创建option文件 --defaults-file=../my.ini [mysql] # 设置mysql客户端默认字符集 default-character-set=utf8 [mys ...

  3. leetcode13_C++罗马数字转整数

    罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II ,即为两个并 ...

  4. php新手需要注意的高效率编程

    1.尽量静态化: 如果一个方法能被静态,那就声明它为静态的,速度可提高1/4,甚至我测试的时候,这个提高了近三倍.   当然了,这个测试方法需要在十万级以上次执行,效果才明显.   其实静态方法和非静 ...

  5. Python Requests库入门——应用实例-百度、360搜索关键词提交

    百度的关键词接口: http://www.baidu.com/s?wd=keyword 360的关键词接口: http://www.so.com/s?q=keyword keyword就是需要查找的关 ...

  6. Scrum立会报告+燃尽图(十月三十日总第二十一次)

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2290 项目地址:https://git.coding.net/zhang ...

  7. 第五次作业psp

    psp 进度条 代码累积折线图 博文累积折线图 psp饼状图 团体合作体会:经过这几天的团队,我感受良多.发现团队协作是一件非常让人兴奋的事情.团队成员们互相帮助,互相协作,让我感受最深的就是当自己为 ...

  8. 六周psp

    本周psp 本周进度条 代码累积折线图 博文字数累积折线图 饼状图

  9. Week4_Linux书本一二两章

    第一章的学习内容就是对Linux内核有一个基本的了解,同时知道一些关于Linux的知识. 学习Linux,可以自己有一台装有Linux操作系统的机器,源代码的作用无可替代: Linux发展历程简介:L ...

  10. this & super

    /* 当本类的成员和局部变量同名用this区分. 当子父类中的成员变量同名用super区分父类.   this和super的用法很相似.   this:代表一个本类对象的引用. super:代表一个父 ...