【学习笔记】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 part
	int ans=(g2[k]-g1[k])-(sp2[y]-sp1[y]);
	ans%=mod;
	//other parts
	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])
		{
			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.另一个计数问题

题解戳这里喵~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

React Element介绍

React Element是React中的核心概念之一&#xff0c;它代表了React应用中的UI元素。React Element并不是真实的DOM节点&#xff0c;而是一个轻量级的、不可变的、描述性的对象&#xff0c;它包含了创建UI所需的类型&#xff08;type&#xff09;、属性&#xff08;props&#xf…

Docker 安装ros 使用rviz 等等图形化程序

Docker 安装ros 使用rviz 等等图形化程序 ubuntu 版本与ros 发行版本对应 如何安装其它版本ros 此时考虑使用docker 易于维护 地址&#xff1a; https://hub.docker.com/r/osrf/ros 我主机是 ubuntu22.04 使用这个标签 melodic-desktop-full 1 clone 镜像到本机 docker pu…

Pytorch使用Dataset加载数据

1、前言&#xff1a; 在阅读之前&#xff0c;需要配置好对应pytorch版本。 对于一般学习&#xff0c;使用cpu版本的即可。参考教程点我 导入pytorch包&#xff0c;使用如下命令即可。 import torch # 注意虽然叫pytorch&#xff0c;但是在引用时是引用torch2、神经网络获取…

鞭炮插画:成都亚恒丰创教育科技有限公司

鞭炮插画&#xff1a;年味里的绚烂记忆 在岁末年初的温柔时光里&#xff0c;总有一抹色彩&#xff0c;能瞬间唤醒沉睡的年味——那便是鞭炮插画中跃动的红与金&#xff0c;成都亚恒丰创教育科技有限公司 它们不仅仅是纸与墨的交织&#xff0c;更是情感与记忆的桥梁&#xff0c…

EI美国工程索引的使用方法及个人使用途径

Ei Compendex &#xff08;美国工程索引&#xff09;是全球最全面的工程索引数据库&#xff0c;涵盖了6大工科学科领域(电子通信、建筑环境、能源资源、化工化学、机械控制及通用工程)&#xff0c;超过190个子学科领域(涉及核技术、生物工程、交通运输、化学和工艺工程、照明和…

科研绘图系列:R语言金字塔图(pyramid plot)

介绍 金字塔图(Pyramid chart)是一种用于展示人口统计数据的图表,特别是用于展示不同年龄段的人口数量。这种图表通常用于展示人口结构,比如性别和年龄的分布。 特点: 年龄分层:金字塔图按年龄分层,每一层代表一个年龄组。性别区分:通常,男性和女性的数据会被分别展…

[K8S]一、Flink on K8S

Kubernetes | Apache Flink 先编辑好这5个配置文件&#xff0c;然后再直接执行 kubectl create -f ./ kubectl get all kubectl get nodes kubectl get pods kubectl get pod -o wide kubectl get cm -- 获取所有的configmap 配置文件 kubectl logs pod_name -- 查看…

C语言 ——— 将一句英语短句中的单词进行倒置

目录 题目要求 代码实现 题目要求 将一句英语短句中的单词进行倒置&#xff0c;标点符号不倒置 如&#xff1a; 输入&#xff1a;"I like chongqing very much," 输出&#xff1a;"much, very chongqing like I" 代码实现 #include<stdio.h> #i…

ssh升级

文章目录 ssh升级一、解包ssh、ssl二、更新安装ssl三、手动更新手动复制库文件四、创建符号链接五、更新库路径六、验证库文件七、设置库路径环境变量八、配置、编译、安装OpenSSH&#xff1a;意外&#xff1a;缺少 zlib 的开发库解决方法&#xff1a; 九、刷新ssh服务、查看ss…

Nginx的访问限制与访问控制

访问限制 访问限制是一种防止恶意访问的常用手段&#xff0c;可以指定同一IP地址在固定时间内的访问次数&#xff0c;或者指定同一IP地址在固定时间内建立连接的次数&#xff0c;若超过网站指定的次数访问将不成功。 请求频率限制配置 请求频率限制是限制客户端固定时间内发…

2024年职业院校大数据实验室建设及大数据实训平台整体解决方案

随着大数据技术的飞速发展&#xff0c;职业院校的大数据实验室建设与实训平台的打造成为教育领域关注的焦点。为了培养适应时代需求的专业人才&#xff0c;2024年的职业院校大数据实验室建设将遵循以下原则与策略&#xff1a; 首要任务是明确实验室建设的学科定位&#xff0c;…

OpenCV:python图像旋转,cv2.getRotationMatrix2D 和 cv2.warpAffine 函数

前言 仅供个人学习用&#xff0c;如果对各位朋友有参考价值&#xff0c;给个赞或者收藏吧 ^_^ 一. cv2.getRotationMatrix2D(center, angle, scale) 1.1 参数说明 parameters center&#xff1a;旋转中心坐标&#xff0c;是一个元组参数(col, row) angle&#xff1a;旋转角度…

【权威发布】2024年互联网技术与信息工程国际会议(ITIEIC 2024)

2024年互联网技术与信息工程国际会议 2024 International Conference on Internet Technology and Information Engineering 【1】会议简介 2024年互联网技术与信息工程国际会议是一个集学术性、实践性和国际性于一体的盛会&#xff0c;将为全球互联网技术与信息工程领域的发展…

C判断一个点在三角形上

背景 鼠标操作时&#xff0c;经常要判断是否命中显示控件&#xff0c;特开发此算法快速判断。 原理 三角形三等分点定理是指在任意三角形ABC中&#xff0c;可以找到三个点D、E和F&#xff0c;使得线段AD、BE和CF均等分三角形ABC。 这意味着三个等分点分别位于三个边界上&…

图解PyTorch中的Transpose操作

在PyTorch中&#xff0c;我们时常会对张量进行转置操作。若张量是二维的&#xff0c;则非常容易理解。若张量维度更高&#xff0c;则会令人摸不到头脑。 高维张量究竟是怎么转置的&#xff1f;简单来说&#xff0c;就是将参与转置的维度抽出来&#xff0c;将内侧的子张量视为一…

EasyCVR视频技术:城市电力抢险的“千里眼”,助力抢险可视化

随着城市化进程的加速和电力需求的不断增长&#xff0c;电力系统的稳定运行对于城市的正常运转至关重要。然而&#xff0c;自然灾害、设备故障等因素常常导致电力中断&#xff0c;给城市居民的生活和企业的生产带来严重影响。在这种情况下&#xff0c;快速、高效的电力抢险工作…

Chromium CI/CD 之Jenkins实用指南2024-如何创建新节点(三)

1. 前言 在前一篇《Jenkins实用指南2024-系统基本配置&#xff08;二&#xff09;》中&#xff0c;我们详细介绍了如何对Jenkins进行基本配置&#xff0c;包括系统设置、安全配置、插件管理以及创建第一个Job。通过这些配置&#xff0c;您的Jenkins环境已经具备了基本的功能和…

昇思25天学习打卡营第09天|保存与加载

在训练网络模型的过程中&#xff0c;实际上我们希望保存中间和最后的结果&#xff0c;用于微调&#xff08;fine-tune&#xff09;和后续的模型推理与部署&#xff0c;本章节我们将介绍如何保存与加载模型。 import numpy as np import mindspore from mindspore import nn fr…

Android TabLayout+ViewPager2如何优雅的实现联动详解

一、介绍 Android开发过程中&#xff0c;我们经常会遇到滑动导航栏的做法&#xff0c;之前的做法就是我们通过ViewGroup来转动&#xff0c;然后通过大量的自定义来完成&#xff0c;将导航栏item与viewpage 滑动&#xff0c;达到业务需求 二、现实方案 通过介绍&#xff0c;我…

【邀请函】庭田科技邀您第五届中国国际复合材料科技大会

第五届中国国际复合材料科技大会暨第七届国际复合材料产业创新成果技术展示&#xff08;ICIE7-新疆&#xff09;将于7月25-27日在新疆乌鲁木齐-国际会展中心举行。上海庭田信息科技有限公司将携多款仿真模拟软件亮相本次大会&#xff0c;诚挚欢迎各位到场咨询了解&#xff01; …