Min25筛
Min25筛
我是沙雕。。。
从yyb博客蒯的
要求:\(\sum_{i=1}^nF(x)\)
\(F(x)\)是积性函数。
\(Min25\)筛能用的前提:质数处的\(f(p)\)值是关于\(p\)的多项式,质数次方处的\(f(p^e)\)值 可以快速计算。
预处理
设完全积性函数\(F'(x)\),在质数处取值\(F(p)=F'(p)\)。
预处理一个\(g\)函数。\(g(n,j)=\sum_{i=1}^nF'(i)[i\in\mathbb{P}\text{ or }\min_{p|i}p>P_j]\)
也就是\(i\)是质数或者\(i\)最小值因子\(>P_j\)的贡献(注意求的是\(F'\))
转移:
\(g(n,j)=\begin{cases}g(n,j-1) (P_j^2>n)\\g(n,j-1)-F'(P_j)[g(\frac{n}{P_j},j-1)-g(P_{j-1},j-1)](P_j\leq n)\end{cases}\)
考虑\(g(n,j-1)-g(n,j)\)。如果\(P_j^2>n\)显然没有多余贡献。
否则会多余的一定是\(P_j\)的倍数,那么因为\(F'\)是完全积性函数,可以将多余的数全部除以\(P_j\),并乘上贡献\(F'(P_j)\)。那么减掉的是\(F'(P_j)\)乘【\(\frac{n}{P_j}\)以内最小质因数\(\geq P_j\)的数的贡献和】。这个值就是\(g(\frac{n}{P_j},j-1)-g(P_{j-1},j-1)\)。前面多算了\(<P_j\)的质数,后面减掉了这一部分。
可以看出只有\(\sqrt n\)内的质数有用,线性筛到\(\sqrt n\)就行了。
后面的\(g(P_{j-1},j-1)\)按照定义等于\(\sum_{i=1}^{P_{j-1}}F'(i)\)。线性筛时预处理一下就行了。
这个\(g\)后面只用了质数处的\(F'\),所以是对的而且很妙
求值
设\(S(n,j)=\sum_{i=1}^nF(i)[\min_{p|i}p>P_j]\),即最小质因数大于\(P_j\)的所有数的\(F\)和,那么要求的答案是\(S(n,0)\)。
\(S\)的递推式为:\(S(n,j)=g(n,|P|)-\sum_{i=1}^{j-1}f(P_i)+\sum_{p_k^e\leq n,k>j}F(p_k^e)(S(\frac{n}{p_k^e},k)+[e>1])\)
前面部分是质数的贡献,后面是合数的
后面的\(\sum\)意思就是枚举合数最小的质因子及次数,因为是积性函数可以直接乘起来。\([e>1]\)意思是如果\(e>1\)那么有一个\(p_k^e\)没算进答案(\(S\)不计算\(1\)的贡献,但\(e=1\)时\(p_k^e\)就是质数已经在前面算过了),要算进答案。
代码
一些细节:
- \(n\)一直整除一个数之后还是\(n\)整除一个数,也就是只需要用到所有\(\frac ni\)。开两个数组\(a1,a2\),对于\(\sqrt n\)的向\(a1\)存,下标为\(\frac ni\),否则向\(a2\)存,下标为\(i\)。两个数组都是\(\sqrt n\)的。
- 由于\(S\)没有算\(1\),最后还要加上\(1\)的贡献。
#include<bits/stdc++.h>
#define il inline
#define vd void
#define mod 1000000007
typedef long long ll;
il ll gi(){
ll x=0,f=1;
char ch=getchar();
while(!isdigit(ch))f^=ch=='-',ch=getchar();
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return f?x:-x;
}
ll n;
int qt;
int pr[100010],yes[100010],cnt,gp1[100010],gp2[100010];
ll w[200010],sw;
int g1[200010],g2[200010];
int id1[100010],id2[100010];
il int S(ll x,int y){
if(pr[y]>=x)return 0;
int p=x<=qt?id1[x]:id2[n/x];
int ret=((0ll+g2[p]-g1[p]-(gp2[y]-gp1[y]))%mod+mod)%mod;
for(int i=y+1;i<=cnt&&1ll*pr[i]*pr[i]<=x;++i){
ll pe=pr[i];
for(int e=1;pe<=x;++e,pe*=pr[i]){
int o=pe%mod;
ret=(ret+1ll*o*(o-1)%mod*(S(x/pe,i)+(e!=1)))%mod;
}
}
return ret;
}
int main(){
#ifdef XZZSB
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
n=gi();qt=sqrt(n);
yes[1]=1;
for(int i=2;i<=qt;++i){
if(!yes[i])pr[++cnt]=i;
for(int j=1;j<=cnt&&i*pr[j]<=qt;++j){
yes[i*pr[j]]=1;
if(i%pr[j]==0)break;
}
}
for(int i=1;i<=cnt;++i)gp1[i]=(gp1[i-1]+pr[i])%mod,gp2[i]=(gp2[i-1]+1ll*pr[i]*pr[i])%mod;//递推时用的质数处F前缀和
for(ll l=1,r;l<=n;l=r+1){//预处理(n/i) & 计算g的j=0边界,边界就是F'的前缀和,由于质数处F(p)是多项式所以可以快速算
r=n/(n/l);w[++sw]=n/r;
g1[sw]=w[sw]%mod;
g2[sw]=(1ll*g1[sw]*(g1[sw]+1)%mod*(g1[sw]*2+1)%mod*166666668%mod-1)%mod;//1..w[sw]平方和
g1[sw]=(1ll*g1[sw]*(g1[sw]+1)%mod*500000004-1)%mod;//1..w[sw]等差数列和
if(n/r<=qt)id1[n/r]=sw;else id2[r]=sw;
}
//j从1到|P|递推g
for(int i=1;i<=cnt;++i){
ll sqr_pi=1ll*pr[i]*pr[i];
for(int j=1;j<=sw&&sqr_pi<=w[j];++j){
ll p=w[j]/pr[i];
p=(p<=qt?id1[p]:id2[n/p]);//定位p的坐标
g1[j]=(g1[j]-1ll*pr[i]*(g1[p]-gp1[i-1]+mod)%mod+mod)%mod;
g2[j]=(g2[j]-1ll*pr[i]*pr[i]%mod*(g2[p]-gp2[i-1]+mod)%mod+mod)%mod;
}
}
printf("%d\n",(S(n,0)+1)%mod);
return 0;
}
Min25筛的更多相关文章
- LOJ# 572. 「LibreOJ Round #11」Misaka Network 与求和(min25筛,杜教筛,莫比乌斯反演)
题意 求 \[ \sum_{i = 1}^{n} \sum_{i = 1}^{n} f(\gcd(i, j))^k \pmod {2^{32}} \] 其中 \(f(x)\) 为 \(x\) 的次大质 ...
- BZOJ-5244 最大真因数(min25筛)
题意:一个数的真因数指不包括其本身的所有因数,给定L,R,求这个区间的所有数的最大真因数之和. 思路:min25筛可以求出所有最小因子为p的数的个数,有可以求出最小因子为p的所有数之和. 那么此题就是 ...
- loj#6235. 区间素数个数(min25筛)
题意 题目链接 Sol min25筛的板子题,直接筛出\(g(N, \infty)\)即可 筛的时候有很多trick,比如只存\(\frac{N}{x}\)的值,第二维可以滚动数组滚动掉 #inclu ...
- 「学习笔记」Min25筛
「学习笔记」Min25筛 前言 周指导今天模拟赛五分钟秒第一题,十分钟说第二题是 \(\text{Min25}\) 筛板子题,要不是第三题出题人数据范围给错了,周指导十五分钟就 \(\text{AK ...
- [总结] min-25筛
再不写总结我又会忘掉啊啊啊啊啊啊啊啊啊 这个\(min-25\)筛主要用来求一个积性函数的前缀和,就像这样\[\sum_{i=1}^n f(i)\] 不过这个积性函数要满足两个条件:质数\(p\)的函 ...
- min25筛学习总结
前言 杜教筛学了,顺便把min25筛也学了吧= =刚好多校也有一道题需要补. 下面推荐几篇博客,我之后写一点自己的理解就是了. 传送门1 传送门2 传送门3 这几篇写得都还是挺好的,接下来我就写下自己 ...
- CodeForces - 83D:Numbers (数学&递归 - min25筛 )
pro:给定三个整数L,R,P求[L,R]区间的整数有多少个是以P为最小因子的.L,R,P<2e9; sol: 一: 比较快的做法是,用函数的思想递归. 用solve(N,P)表示求1到N有多少 ...
- 莫比乌斯反演/线性筛/积性函数/杜教筛/min25筛 学习笔记
最近重新系统地学了下这几个知识点,以前没发现他们的联系,这次总结一下. 莫比乌斯反演入门:https://blog.csdn.net/litble/article/details/72804050 线 ...
- hdu6607 min25筛+杜教筛+伯努利数求k次方前缀和
推导过程类似https://www.cnblogs.com/acjiumeng/p/9742073.html 前面部分min25筛,后面部分杜教筛,预处理min25筛需要伯努利数 //#pragma ...
随机推荐
- IDEA设置虚拟机参数
第一步:打开“Run->Edit Configurations”菜单 第二步:选择“VM Options”选项,输入你要设置的VM参数 第三步:点击“OK”.“Apply”后设置完成
- scanf加不加\n?
近两天用vs2013敲代码碰到的问题 关于scanf小括号中加不加\n的区别 例程序如下所示: 第一个程序: int main(){ ; printf("你会去敲代码吗?(选择1 or 0) ...
- Java自学-数组 创建数组
Java 如何创建一个数组 数组是一个固定长度的,包含了相同类型数据的 容器 步骤 1 : 声明数组 int[] a; 声明了一个数组变量. []表示该变量是一个数组 int 表示数组里的每一个元素都 ...
- JAVA基础之JSP与EL技术、JSTL技术
要牢记jsp四大作用域(pageContext域:当前jsp页面范围 request域:一次请求 session域:一次会话 application域:整个web应用)以及九大内置对 ...
- Linux内核同步机制之completion
内核编程中常见的一种模式是,在当前线程之外初始化某个活动,然后等待该活动的结束.这个活动可能是,创建一个新的内核线程或者新的用户空间进程.对一个已有进程的某个请求,或者某种类型的硬件动作,等等.在这种 ...
- 笔谈HTTP Multipart POST请求上传文件
公司一做iOS开发的同事用HTTP Multipart POST请求上传语音数据,但是做了两天都没搞定,项目经理找到我去帮忙弄下.以前做项目只用过get.post,对于现在这个跟服务器交互的表单请求我 ...
- GitHub Java项目推荐|不需要 ROOT权限的类似按键精灵的自动操作
不需要 ROOT 权限的类似按键精灵的自动操作软件,可以实现自动点击.滑动.输入文字.打开应用等.Auto.js 的大部分用户用它来点赞.签到.刷游戏 项目分析 仓库名称:Auto.js 标星(sta ...
- vue-cli 移动端项目如何在手机上调试预览
这里分享下如何在webpack工具构建下的vue项目,在手机端调试和预览,言归正传. 1.电脑和手机连接到同一个WIFI a.台式电脑和手机同时链接一个路由器,使用同一个wifi: b.笔记本也可以直 ...
- Python学习日记(三十) Socket模块使用
Socket(套接字) 套接字是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像文件一样的打开.读写和关闭等操作.套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信.网 ...
- Docker(5):Docker镜像基本操作(上)
1.获取镜像 可以使用docker pull 命令从网络上下载镜像.该命令的格式为docker pull NAME[:TAG].对于Docker镜像来说,如果不显示地指定TAG,则默认会选择lates ...