【学习笔记】min_25筛

背景

GDCPC2024
出题人:出这道 min25 筛是给大家增加过题数的 [呲牙][大哭][呲牙][大哭]

min25筛是干啥的

快速求一个积性函数 F ( x ) F(x) F(x) 的前缀和
这个 F ( x ) F(x) F(x) 需要满足:
F ( p ) = ∑ i = 0 a i p i F(p)=\sum_{i=0}a_ip^i F(p)=i=0aipi,也就说在质数处 F ( p ) F(p) F(p) 是关于 p p p 的多项式
并且 F ( p k ) F(p^k) F(pk) 需要能够快速计算
比杜教筛适用范围更广。
时间复杂度 O ( n 3 4 l o g n ) O(\frac{n^{\frac{3}{4}}}{logn}) O(lognn43)

Step 1 分类

先对 i i i 按质数和合数分类。
∑ i = 1 n F ( i ) = F ( 1 ) + ∑ p i s a p r i m e n F ( p ) + ∑ x i s a c o m p o s i t e n F ( x ) \sum_{i=1}^nF(i)=F(1) + \sum_{p\ is\ a\ prime}^nF(p)+\sum_{x\ is\ a\ composite}^nF(x) i=1nF(i)=F(1)+p is a primenF(p)+x is a compositenF(x)
由积性函数的性质,可以在合数那里提出一个 F ( p e ) F(p^e) F(pe)
F ( 1 ) + ∑ p n F ( p ) + ∑ p ≤ n , p e ≤ n F ( p e ) ( ∑ m i n p > p , i ⌊ n p ⌋ F ( i ) ) F(1)+\sum_{p}^nF(p)+\sum_{p\leq\sqrt{n},\ p^e\leq n}F(p^e)(\sum_{minp>p,\ i}^{\left\lfloor\frac{n}{p}\right\rfloor}F(i)) F(1)+pnF(p)+pn , penF(pe)(minp>p, ipnF(i))

Step2 预处理

g ( n , j ) g(n,j) g(n,j) 为前 n n n F ( i ) F(i) F(i) 经历 j j j 次埃氏筛,剩下的 F ( i ) F(i) F(i) 值之和。最后我们需要用到的值是
g ( n , ∣ P ∣ ) = ∑ p n F ( p ) g(n,|P|) =\sum_{p}^nF(p) g(n,P)=pnF(p)
由于 F ( p ) F(p) F(p) 是关于 p p p 的多项式,所以我们只需要令 F ( i ) = i k F(i)=i^k F(i)=ik 对应多项式中其中一项,然后再把每一项加起来。即:
g ( n , j ) = ∑ i = 2 n [ i i s a p r i m e o r m i n p ( i ) > p j ] i k g(n,j) = \sum_{i=2}^n[i\ is\ a\ prime\ or\ minp(i)>p_j]i^k g(n,j)=i=2n[i is a prime or minp(i)>pj]ik
其中 m i n p ( i ) minp(i) minp(i) i i i 的最小质因子, p j p_j pj为第 j j j 大的质数。
那么,这玩意怎么求呢?注意,这里的 n n n 很大,不能直接线性筛。

考虑如何从 g ( n , j − 1 ) g(n,j-1) g(n,j1) 转移到 g ( n , j ) g(n,j) g(n,j),也就是,我们要考虑第 j j j 次埃氏筛筛掉了什么。
首先,经历了前面 j − 1 j-1 j1 次埃氏筛之后,剩下的数要么是质数,要么 m i n p > p j − 1 minp >p_{j-1} minp>pj1。所以第 j j j 次筛掉的数一定是 m i n p = p j minp=p_j minp=pj 的合数。
并且, p j p_j pj 能筛掉的最小的数是 p j 2 p_j^2 pj2
我们可以从这些合数提出一个 p j p_j pj,根据完全积性函数的性质,得到转移式:
g ( n , j ) = { g ( n , j − 1 ) − p j k ( g ( n p j , j − 1 ) − g ( p j − 1 , j − 1 ) ) , p j 2 ≤ n g ( n , j − 1 ) , p j 2 > n g(n,j)=\begin{cases} g(n,j-1)-p_j^k(g(\frac{n}{p_j},j-1)-g(p_{j-1},j-1)), & p_j^2 \leq n \\ g(n,j-1), & p_j^2>n \end{cases} g(n,j)={g(n,j1)pjk(g(pjn,j1)g(pj1,j1)),g(n,j1),pj2npj2>n
为什么要减去 g ( p j − 1 , j − 1 ) g(p_{j-1},j-1) g(pj1,j1)?
g ( p j − 1 , j − 1 ) = ∑ i = 1 j − 1 p j g(p_{j-1},j-1)=\sum_{i=1}^{j-1}p_j g(pj1,j1)=i=1j1pj,前面的 g g g 经历 j − 1 j-1 j1 次埃氏筛会把质数保留下来,而我们只需要减掉合数,所以我们要把质数去掉。
而且, p j − 1 p_{j-1} pj1 n \sqrt n n 以内的数,可以使用线性筛预处理前缀和,也就是
s p j = ∑ i = 1 j f ( p i ) = g ( p j , j ) sp_j=\sum_{i=1}^jf(p_i)=g(p_j,j) spj=i=1jf(pi)=g(pj,j)
那么我们要的东西 g ( n , ∣ P ∣ ) g(n,|P|) g(n,P) 的质数集合 P P P 为不超过 n \sqrt n n 的质数集。
但是 n n n 还是太大了,我们依旧无法一个一个地把 g g g 求出来。但是我们又会想到另一个重要结论:
⌊ ⌊ n a ⌋ b ⌋ = ⌊ n a b ⌋ \left\lfloor \frac{\left\lfloor \frac{n}{a}\right\rfloor}{b}\right\rfloor = \left\lfloor\frac{n}{ab}\right\rfloor ban=abn
也就说,我们需要的数都能被表示成 x x x 或者 ⌊ n x ⌋ \left\lfloor\frac{n}{x}\right\rfloor xn 的形式。这些数一共只有 O ( n ) O(\sqrt n) O(n ) 个。
那么如何访问这 O ( n ) O(\sqrt n) O(n ) 个位置呢?
如果偷懒用 m a p map map 的话会多一个 l o g log log,我们可以用两个数组 i d 1 , i d 2 id1,\ id2 id1, id2 存储它们的下标。

if(w[tot]<=sqr) id1[w[tot]]=tot;
else id2[n/w[tot]]=tot;

step3 求答案

我们令 S ( n , j ) S(n,j) S(n,j) 2 2 2~ n n n m i n p > p j minp>p_j minp>pj 的函数值之和,即:
S ( n , j ) = ∑ i = 2 n [ m i n p ( i ) > p j ] S(n,j)=\sum_{i=2}^n[minp(i)>p_j] S(n,j)=i=2n[minp(i)>pj]
那么我们要求的答案就是 S ( n , 0 ) S(n,0) S(n,0)

同样的,我们依旧把和分成质数的和,合数的和。枚举它们最小的因子,那么就有下面的转移:
S ( n , j ) = g ( n , ∣ P ∣ ) − s p j + ∑ p k e ≤ n & k > x f ( p k e ) ( S ( n p k e , k ) + [ e ≠ 1 ] ) S(n,j)=g(n,|P|)-sp_j+\sum_{p_k^e\leq n \&k>x}f(p_k^e)(S(\frac{n}{p_k^e},k)+[e≠1]) S(n,j)=g(n,P)spj+pken&k>xf(pke)(S(pken,k)+[e=1])
前面的 g ( n , ∣ P ∣ ) − s p j g(n,|P|)-sp_j g(n,P)spj 显然是质数的答案部分。
后面的合数同样可以根据积性函数的性质提出 f ( p k e ) f(p_k^e) f(pke)
需要注意的是, S ( n p k e , k ) S(\frac{n}{p_k^e},k) S(pken,k) 是会把 p k e [ e > 1 ] p_k^e[e>1] pke[e>1] 筛掉的,所以要把它给补上,也就是加上 [ e ≠ 1 ] [e≠1] [e=1]

至此,min25筛的流程就讲完啦。

例题

【模板】Min_25 筛

在这里插入图片描述
在这里插入图片描述

思路

显然, f ( p ) = p 2 − p f(p)=p^2-p f(p)=p2p,那我们分别对它的二次项,一次项进行预处理,然后求解即可。
记得最后把 f ( 1 ) f(1) f(1) 加上

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+7,inf=1e18,mod=1e9+7;
vector<int> g1(N),g2(N),id1(N),id2(N),sp1(N),sp2(N),p,w(N);
int sqr,tot=0,n;
int power(int x,int t)
{int b=1;while(t){if(t&1) b=b*x%mod;x=x*x%mod; t>>=1;}return b;
}
void init(int n)
{vector<bool> bz(n+1);p.push_back(0);tot=0;bz[1]=1;for(int i=1; i<=n; i++){if(!bz[i]){p.push_back(i);int now=p.size()-1;sp1[now]=(sp1[now-1]+i)%mod;sp2[now]=(sp2[now-1]+i*i%mod)%mod;}for(auto j:p){if(!j) continue;if(i*j>n) break;bz[i*j]=1;if(i%j==0) break;}}
}
int S(int x,int y)
{if(x<=1||p[y]>=x) return 0;int k=(x<=sqr)?id1[x]:id2[n/x];//prime partint ans=(g2[k]-g1[k])-(sp2[y]-sp1[y]);ans%=mod;//other partsfor(int k=y+1; k<p.size()&&p[k]*p[k]<=x; k++){int t=p[k];for(int e=1; t<=x; e++,t*=p[k]){int p=t%mod;// avoid overflow(ans+=p*(p-1)%mod*(S(x/t,k)+(e!=1))%mod)%=mod;}}return ans;
}
void O_o()
{//f(p^k) = p^k(p^k - 1)cin>>n;sqr=sqrt(n);init(sqr);//let g(n,0) = \sum_{i=1}^n f'(i) int inv2=power(2,mod-2),inv3=power(3,mod-2);for(int i=1,j; i<=n; i=j+1){j=n/(n/i);w[++tot]=n/i;int now=w[tot]%mod;g1[tot]=now*(now+1)%mod*inv2%mod-1;g2[tot]=now*(now+1)%mod*(2*now+1)%mod*inv2%mod*inv3%mod-1;// 4+9+16...if(w[tot]<=sqr) id1[w[tot]]=tot;else id2[n/w[tot]]=tot;}//get g(n,|P|)for(int i=1; i<p.size(); i++){for(int j=1; j<=tot&&p[i]*p[i]<=w[j]; j++){//get g(w[j],i)int k=w[j]/p[i]<=sqr?id1[w[j]/p[i]]:id2[n/(w[j]/p[i])];//g(w[j],i) = g(w[j],i-1) - f'(p[i])*(g(w[k],j-1)-sp[i-1])(g1[j]-=p[i]*(g1[k]-sp1[i-1]+mod)%mod)%=mod;(g2[j]-=p[i]*p[i]%mod*(g2[k]-sp2[i-1]+mod)%mod)%=mod;}}int ans=S(n,0)+1;(ans+=mod)%=mod;cout<<ans<<"\n";
}
signed main()
{ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);cout<<fixed<<setprecision(2);int T=1;
//	cin>>T;while(T--){O_o();}
}

简单的函数

在这里插入图片描述
在这里插入图片描述

思路

先考虑质数处的值,显然除了 2 以外,所有质数都是奇数。但我们可以先令 f ( p ) = p − 1 f(p)=p-1 f(p)=p1,最后答案再加上 2。
那么我们需要对 p p p − 1 -1 1 进行预处理,然后直接套 min25 筛即可。

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+7,inf=1e18,mod=1e9+7;
vector<int> g1(N),g0(N),sp1(N),id1(N),id2(N),p,w(N);
int n,sqr,tot;
void init(int n)
{p.push_back(0);tot=0;vector<bool> bz(n+1);for(int i=2; i<=n; i++){if(!bz[i]){p.push_back(i);int now=p.size()-1;sp1[now]=(sp1[now-1]+i)%mod;}for(auto j:p){if(!j) continue;if(i*j>n) break;bz[i*j]=1;if(i%j==0) break;}}
}
int S(int x,int y)
{if(x<=1||p[y]>=x) return 0;int k=(x<=sqr)?id1[x]:id2[n/x];int ans=g1[k]-g0[k]-sp1[y]+y;ans%=mod;for(int k=y+1; k<p.size()&&p[k]*p[k]<=x; k++){int t=p[k];for(int e=1; t<=x; e++,t*=p[k]){(ans+=(p[k]^e)*(S(x/t,k)+(e!=1))%mod)%=mod;}}return ans;
}
void O_o()
{cin>>n;if(n==1){cout<<1<<"\n";return;}sqr=sqrt(n);init(sqr);for(int i=1,j; i<=n; i=j+1){j=n/(n/i);w[++tot]=n/i;int now=w[tot]%mod;g1[tot]=now*(now+1)/2%mod-1;g0[tot]=now-1;if(w[tot]<=sqr) id1[w[tot]]=tot;else id2[n/w[tot]]=tot;}for(int i=1; i<p.size(); i++){for(int j=1; j<=tot,p[i]*p[i]<=w[j]; j++){int k=w[j]/p[i]<=sqr?id1[w[j]/p[i]]:id2[n/(w[j]/p[i])];//g(w[j],i) = g(w[j],i-1) - f'(p[i])*(g(w[k],j-1)-sp[i-1])(g1[j]-=p[i]*(g1[k]-sp1[i-1])%mod)%=mod;(g0[j]-=(g0[k]-(i-1))%mod)%=mod;}}int ans=S(n,0)+3;(ans+=mod)%=mod;cout<<ans<<"\n";
}
signed main()
{ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);cout<<fixed<<setprecision(2);int T=1;
//	cin>>T;while(T--){O_o();}
}

【GDCPC2024】J.另一个计数问题

题解戳这里喵~

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

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

相关文章

Qt各个版本安装的保姆级教程

文章目录 前言Qt简介下载Qt安装包安装Qt找到Qt的快捷方式总结 前言 Qt是一款跨平台的C图形用户界面应用程序开发框架&#xff0c;广泛应用于桌面软件、嵌入式软件、移动应用等领域。Qt的强大之处在于其高度的模块化和丰富的工具集&#xff0c;可以帮助开发者快速、高效地构建出…

C++: 位图和布隆过滤器

目录 一、位图 1.1 概念 1.2 应用 1.3 模拟实现 1.31 把比特位上的值设置为1 1.32 把比特位上的值设置为0 1.33 检测比特位上的值是否是1 1.34 代码 二、布隆过滤器 2.1 概念 2.2 优点 2.3 缺点 2.4模拟实现 一、位图 1.1 概念 运用哈希的思想&#xff0c;将整型…

【前端数据层高可用架构】

前端数据层高可用架构 前后端架构模式如下图 在这个架构下,客端数据可用率计算方式: 因此整体数据可用性分析表如下: 只有在客端和 BFF 都正常的情况下数据才能可用,而这种情况占比不是很高,因此整体的用户体验就不是很好。 本次建设目标 本文的设计方案就是要解决…

Python Linux环境(Centos8)安装minicoda3+jupyterlab

文章目录 安装miniconda安装python环境启动 最近服务器检查&#xff0c;我下面的服务器有漏洞&#xff0c;不得已重装了&#xff0c;正好记录下怎么从零到python写代码。 安装miniconda miniconda是anconda的精简版&#xff0c;就是管理python环境的得力助手。 # 创建一个名…

C语言 do while循环语句练习 下

猜数字游戏实现 //猜数字游戏 //电脑产生 一个随机数&#xff08;1-100) //猜数字 //猜大了 //猜小了 //直到猜对了&#xff0c;结束 #include <stdlib.h> #include <time.h> void menu() {printf("********************************\n");printf("…

【Redis7】高阶篇

1 Redis单线程 VS 多线程(入门篇) 1.1 面试题 redis到底是单线程还是多线程&#xff1f; IO多路复用听说过吗&#xff1f; redis为什么快&#xff1f; 1.2 Redis为什么选择单线程&#xff1f; 1.2.1 是什么 这种问法其实并不严谨&#xff0c;为啥这么说呢? Redis的版本…

怎么将图片插入excel单元格中

首先选中单元格选择插入 在图片位置选择插入图片的位置 然后就插入成功了&#xff0c;一开始会觉得图片是附在表格上面的&#xff0c;并不在单元格里面&#xff0c;但是右边有一个小图片的图标&#xff0c;点击它可以缩小到单元格里面&#xff0c;再点击就是放大&#xff1b;

【无人值守】对数据中心电力分配系统发展的影响

数据中心在现代信息发展中承载着巨量数据的计算、存储、挖掘、分析和应用等多个方面的功能&#xff0c;是国计民生各行业的多样化的信息化的资产。对稳定的运行与安全运维是基本需求也是重要的保障。 数据中心属于高能耗产业&#xff0c;对用电负荷大且要求极度稳定。除了对电力…

ROS、pix4、gazebo、qgc仿真ubuntu20.04

一、ubuntu、ros安装教程比较多&#xff0c;此文章不做详细讲解。该文章基于ubuntu20.04系统。 pix4参考地址&#xff1a;https://docs.px4.io/main/zh/index.html 二、安装pix4 1. git clone https://github.com/PX4/PX4-Autopilot.git --recursive 2. bash ./PX4-Autopilot…

华为od 100问 持续分享4-目标院校及分数线

我是一名软件开发培训机构老师&#xff0c;我的学生已经有上百人通过了华为OD机试&#xff0c;学生们每次考完试&#xff0c;会把题目拿出来一起交流分享。 重要&#xff1a;2024年5月份开始&#xff0c;考的都是OD统一考试&#xff08;D卷&#xff09;&#xff0c;题库已经整…

TikTok账号矩阵运营怎么做?

这几年&#xff0c;聊到出海避不过海外抖音&#xff0c;也就是TikTok&#xff0c;聊到TikTok电商直播就离不开账号矩阵&#xff1b; 在TikTok上&#xff0c;矩阵养号已经成为了出海电商人的流行策略&#xff0c;归根结底还是因为矩阵养号可以用最小的力&#xff0c;获得更大的…

RTI DDS大数据碎片

有两种类型的碎片&#xff1a;IP级碎片和DDS级碎片。 当传输层&#xff08;通常是UDP或TCP&#xff09;提供的有效载荷超过适合链路帧的最大有效载荷大小&#xff08;也称为链路最大传输单元或链路MTU&#xff09;时&#xff0c;就会发生IP级碎片。如果网络是以太网&#xff0…

【大模型】FAISS向量数据库记录:从基础搭建到实战操作

文章目录 文章简介Embedding模型BGE-M3 模型亮点 FAISS是什么FAISS实战安装faiss加载Embedding模型创建FAISS数据库搜索FAISS数据删除FAISS数据保存、加载FAISS索引 总结 本人数据分析领域的从业者&#xff0c;拥有专业背景和能力&#xff0c;可以为您的数据采集、数据挖掘和数…

通用图形处理器设计GPGPU基础与架构(二)

一、前言 本系列旨在介绍通用图形处理器设计GPGPU的基础与架构&#xff0c;因此在介绍GPGPU具体架构之前&#xff0c;需要了解GPGPU的编程模型&#xff0c;了解软件层面是怎么做到并行的&#xff0c;硬件层面又要怎么配合软件&#xff0c;乃至定出合适的架构来实现软硬件协同。…

15- 微分方程

对三角函数不敏感

Linux - 基础开发工具(yum、vim、gcc、g++、make/Makefile、git、gdb)

目录 Linux软件包管理器 - yum Linux下安装软件的方式 认识yum 查找软件包 安装软件 如何实现本地机器和云服务器之间的文件互传 卸载软件 Linux编辑器 - vim vim的基本概念 vim下各模式的切换 vim命令模式各命令汇总 vim底行模式各命令汇总 vim的简单配置 Linux编译器 - gc…

提高记忆力7种自然(高效)的方法

你的记忆力如何?你的认知功能是否如你所希望的那样强大? 如果没有,那么你肯定会对将在本文中与你分享的记忆改善技巧感兴趣的。 不管你怎么想,或者别人怎么说,提高你记忆信息的能力是完全有可能的。只要知道正确的方法即可。(别担心,你并不需要做出任何重大的生活方式改…

10 个 OKR 提示将改变您执行 OKR 的方式

我们都喜欢好的表情包&#xff0c;因为它们很有趣&#xff0c;可以分享&#xff0c;非常适合与同事们一起开怀大笑。表情包可以为工作场所带来一种友情和轻松的感觉&#xff0c;从而建立一种健康的团队文化&#xff0c;这一点很重要。然而&#xff0c;我们都知道它们也会分散注…

怎么减少pdf格式的内存,怎么减少pdf文件大小

在数字化时代&#xff0c;pdf文件因其格式稳定、兼容性强等特点&#xff0c;成为工作与学习中的常用文档格式。然而&#xff0c;较大的pdf文件往往给存储和传输带来不便。本文将为你详细介绍如何巧妙减小pdf文件内存&#xff0c;助你轻松解决文件传输和存储的烦恼。 让我们来看…

基于SpringBoot的招生管理系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Eclipse、Navicat、Maven 系统展示 首页 个人中心 学生管理 专…