Min_25筛 学习小记
前言
为什么叫学习小记呢?因为暂时除了模板题就没有做其他的东西了。(雾
这个东西折磨了我一整天,看得我身不如死,只好结合代码理解题解,差点死在机房。(话说半天综合半天竞赛真是害人不浅)
为了以后忘了再受荼毒,这里还是写一下,如果有人会看到的话,希望可以帮助到吧。(话说这个东西我已经拖了好久了啊!!!)
(话说我怎么这么多话说啊?!!)
Min_25 筛
这个东西是由聚聚\(\texttt{Min-25}\)发明了,所以我们称之为\(\texttt{Min-25}\)筛。(感觉有点民科了)那就不废话了,进入正言了。
下面的\(\mathbb{P}\)指的是质数集合,\(\mathbb{P_i}\)指的是第\(i\)个质数,其中第\(0\)个质数为\(0\)。一个最小质因数可能等于它本身。
我们考虑对于一个积性函数求和,我们可能会想到杜教筛或者洲阁筛(尽管我不是很会洲阁筛),但是两种筛法并不是很具有普遍性,特别是杜教筛。
我们考虑一个具体问题,我们现在设一个积性函数\(f(p^k)=p^k(p^k-1)\),其中\(p\)为质数。我们需要求出\(\sum_{i=1}^{n} f(i)\)。
我们发现对于这个问题我们可以分成两个部分进行考虑,一部分为质数,另一部分为合数,所以即为:
\]
其中\(\texttt{LPF(i)}\)表示\(i\)的最小质因子(\(\texttt{Lowest Prime Factor}\))。
这个式子很好理解,可能稍微难一点的就是为什么\(p\le \sqrt n\),这是因为\(\texttt{LPF(n)}\le \sqrt n,s.t. n\notin \mathbb{P}\)。
我们发现这个式子似乎不好继续往下面搞了。
于是,我们构造一种函数\(g(n,i)\)(鬼知道这是怎么想到的),定义为:
\]
\(k\)就是我们把\(f(x)\)拆成单项式唯一存在的指数。比如这道题我们是\(f(p)=p(p-1)\),我们就拆成\(p^2-p\),于是\(k\)分别为\(1\)和\(2\)。
我们考虑如何求出\(g(n,i)\),我们不难得出转移式:
g(n,i-1) (\mathbb{P_i}^2>n)\\
g(n,i-1)-\mathbb{P_i}^k(g(\lfloor\frac{n}{\mathbb{P_i}}\rfloor,i-1)-g(\mathbb{P_{i-1}},i-1))
\end{array}\right.\]
这里还是稍微解释一下吧。很显然的是,我们的\(g(n,i)\)一定是\(g(n,i-1)\)减去最小质因数恰好为\(\mathbb{P_i}\)的数的贡献,而\(x^k\)又是完全积性函数,所以可以提出一个\(\mathbb{P_i}^k\)出来。又因为\(\mathbb{P_i}\)是最小质因数,所以能产生贡献的数除了\(\mathbb{P_i}\)的最小质因数一定不比\(\mathbb{P_i}\)小。
需要提醒的是,后文里面的\(g\)其实是把单项式又重新组合成多项式的,如果不是很理解可以见代码。
我们发现,我们如果设:
\]
我们就可以在\(S\)和\(g\)之间连接起某种关系,即:
\]
\(|\mathbb{P}|\)就是平方小于等于\(n\)的质数的个数,意思就是小于等于\(n\)的质数的\(f\)之和,又因为要最小质因数大于\(\mathbb{P-i}\),所以减去\(\sum_{x=1}^{i-1} f(\mathbb{P_x})\)。后面那一部分的解释跟上个部分差不多,只是需要注意最小质因数要大于\(\mathbb{P_i}\)。
最后的答案显然就是\(S(n,0)\)。
这里还有一些细节需要提,我们发现这里面函数所有的自变量都可以表示成\(\lfloor\frac{n}{x}\rfloor\),于是我们其实需要的数只有\(\sqrt n\)个。我们直接离散化一下就好了,空间其实是可以用根号分治做到\(\Theta(\sqrt n)\)的。具体见代码。
模板题代码
#include <bits/stdc++.h>
using namespace std;
#define Int register int
#define mod 1000000007
#define ll long long
#define MAXN 200005
int mul (int x,int y){return 1ll * x * y % mod;}
int dec (int x,int y){return x >= y ? x - y : x + mod - y;}
int add (int x,int y){return x + y >= mod ? x + y - mod : x + y;}
ll n,sw,w[MAXN];
int sq,cnt,g1[MAXN],g2[MAXN],id1[MAXN],id2[MAXN],gp1[MAXN],gp2[MAXN],pri[MAXN],vis[MAXN];
int S (ll x,int y){
if (pri[y] >= x) return 0;
int p = x <= sq ? id1[x] : id2[n / x],ret = dec (dec (g2[p],g1[p]),dec (gp2[y],gp1[y]));
for (Int i = y + 1;i <= cnt && 1ll * pri[i] * pri[i] <= x;++ i){
ll pk = pri[i];
for (Int k = 1;pk <= x;++ k,pk *= pri[i]){
int o = pk % mod;ret = add (ret,mul (o,mul (o - 1,S (x / pk,i) + (k != 1))));
}
}
return ret;
}
template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
signed main(){
read (n);sq = sqrt (n);
for (Int i = 2;i <= sq;++ i){
if (!vis[i]) pri[++ cnt] = i,gp1[cnt] = add (gp1[cnt - 1],i),gp2[cnt] = add (gp2[cnt - 1],mul (i,i));
for (Int j = 1;j <= cnt && i * pri[j] <= sq;++ j){
vis[i * pri[j]] = 1;
if (i % pri[j] == 0) continue;
}
}
for (ll l = 1,r;l <= n;l = r + 1){
r = n / (n / l);w[++ sw] = n / r;g1[sw] = w[sw] % mod;
g2[sw] = dec (1ll * g1[sw] * (g1[sw] + 1) % mod * (2 * g1[sw] + 1) % mod * 166666668 % mod,1);
g1[sw] = dec (1ll * g1[sw] * (g1[sw] + 1) % mod * 500000004 % mod,1);
if (n / r <= sq) id1[n / r] = sw;else id2[r] = sw;
}
for (Int i = 1;i <= cnt;++ i){
ll sqr = 1ll * pri[i] * pri[i];
for (Int j = 1;j <= sw && w[j] >= sqr;++ j){
ll p = w[j] / pri[i];p = (p <= sq ? id1[p] : id2[n / p]);
g1[j] = dec (g1[j],mul (pri[i],dec (g1[p],gp1[i - 1])));
g2[j] = dec (g2[j],mul (mul (pri[i],pri[i]),dec (g2[p],gp2[i - 1])));
}
}
write (add (S (n,0),1)),putchar ('\n');
return 0;
}
P.S.
据说\(\texttt{Min-25}\)筛的时间复杂度为\(\Theta(\frac{n^{\frac{3}{4}}}{\log n})\),也有人说是渐线性时间复杂度\(\Theta(n^{1-\epsilon})\),不过据说证实了是前者。空间复杂度离散化之后可以做到\(\Theta(\sqrt n)\)。
我们仔细来看\(\texttt{Min-25}\)筛如何降低时间复杂度的过程,发现我们用在自变量为质数时相同的完全积性的函数去解决了当取值为质数的时候的值,之后再用积性函数的性质解决合数的和。不得不说,\(\texttt{Min-25}\)简直是个天才。\(\text{Min-25 Orz Orz Orz}\)
这里解释一下为什么质数只需要筛到\(\sqrt n\),这是因为\(S\)函数所需的无非是枚举最小质因数,而最小质因数一定不大于\(\sqrt n\)。
Min_25筛 学习小记的更多相关文章
- min_25 筛学习小记
min_25筛 由 dalao min_25 发明的筛子,据说时间复杂度是极其优秀的 \(O(\frac {n^{\frac 3 4}} {\log n})\),常数还小. 1. 质数 \(k\) 次 ...
- Min_25 筛 学习笔记
原文链接https://www.cnblogs.com/zhouzhendong/p/Min-25.html 前置技能 埃氏筛法 整除分块(这里有提到) 本文概要 1. 问题模型 2. Min_25 ...
- Min_25筛 学习笔记
这儿只是一个简单说明/概括/总结. 原理见这: https://www.cnblogs.com/cjyyb/p/9185093.html https://www.cnblogs.com/zhoushu ...
- min_25筛学习笔记【待填坑】
看见ntf和pb两位大佬都来学了,然后就不自觉的来学了. 我们考虑这样一个问题. $$ans=\sum_{i=1}^nf(i)$$其中$1\leq n\leq 10^{10}$ 其中$f(i)$是一个 ...
- 洲阁筛 & min_25筛学习笔记
洲阁筛 给定一个积性函数$F(n)$,求$\sum_{i = 1}^{n}F(n)$.并且$F(n)$满足在素数和素数次幂的时候易于计算. 显然有: $\sum_{i = 1}^{n} F(n) = ...
- Min_25筛学习笔记
感觉好好用啊 Luogu上的杜教筛模版题一发 Min_25抢到了 rank1 $ Updated \ on 11.29 $被 STO txc ORZ踩爆啦 前言 $ Min$_$25$筛可以求积性函数 ...
- $Min\_25$筛学习笔记
\(Min\_25\)筛学习笔记 这种神仙东西不写点东西一下就忘了QAQ 资料和代码出处 资料2 资料3 打死我也不承认参考了yyb的 \(Min\_25\)筛可以干嘛?下文中未特殊说明\(P\)均指 ...
- [算法]Min_25筛
前言 本篇文章中使用的字母\(p\),指\(\text{任意的} p \in \text{素数集合}\) 应用场景 若函数\(f(x)\)满足, \(f(x)\)是积性函数 \(f(p)\)可以使用多 ...
- luogu P5325 Min_25筛
LINK:Min_25筛 新版感觉有点鬼畜 而且旧版的也够用了至少. 这个并不算很简单也不算很困难的知识点 学起来还是很麻烦的. (误入了很多dalao的blog 说的云里雾里的 甚是懵逼 这里推荐几 ...
随机推荐
- canvas——离屏
离屏操作: 1.创建一个新的离屏canvas; 2.把一些复杂额绘画操作(背景),画在离屏canvas上: 3.将离屏canvas通过drawImage(离屏canvas对象,x1,y1,offcan ...
- android kotlin determine file type from bytes 根据文件内容识别文件类型,类似python的filetype
尝试了 URLConnection.guessContentTypeFromStream(ByteArrayInputStream(bytes)) 和 Tika().detect(bytes) 一个识 ...
- kubeadm方式搭建K8S集群
一.kubeadm介绍 二.安装要求 三.集群规划 四.环境初始化(在每个服务器节点操作) 1.关闭防火墙 2.关闭selinux 3.关闭swap 4.根据规划设置主机名 5.在Master添加ho ...
- Geode member发现机制
Geode member发现机制 Apache Geode 为集群和客户端服务器间提供了多种member 发现机制,具体如下: Peer Member Discovery Standalone Mem ...
- mac、ip、udp头解析
一.MAC帧头定义 /*数据帧定义,头14个字节,尾4个字节*/ typedef struct _MAC_FRAME_HEADER { char m_cDstMacAddress[6]; // ...
- java9的JShell小工具和编译器两种自动优化
一.按顺序逐步执行的脚本程序: 二.编译器自动优化 1.不超数据类型范围编译器自动添加强转操作: 2.一但发生运算,byte/short/char都会自动提升为Int,当只有常量参与运算时,编译器会先 ...
- Java-SpringBoot整合SpringCloud
SpringBoot整合SpringCloud 1. SpringCloud特点 SpringCloud专注于为典型的用例和扩展机制提供良好的开箱即用体验,以涵盖其他情况: 分布式/版本化配置 服务注 ...
- 法术迸发(Spellburst)
描述 法术迸发 (EN:Spellburst ) 是一种在<通灵学园>中加入的关键字异能,在玩家打出一张法术牌后触发,只能触发一次. 若随从在法术结算过程中死亡,则不会触发效果 思路 首先 ...
- golang指针接收者和值接收者方法调用笔记
初学go时很多同学会把 值接收者 和 指针接收者 的方法相互调用搞混淆,好多同学都只记得指针类型可以调用值接收者方法和指针接收者方法,而值类型只能调用值接收者方法,其实不然,在某些情况下,值类型也是可 ...
- HDU 6170 Two strings( DP+字符串匹配)
http://acm.hdu.edu.cn/showproblem.php?pid=6170 题目大意: 给出两个字符串s1和s2(长度小于等于2500). s1是一个正常的包含大小写字母的字符串,s ...