Min_25 筛

yyb好神仙啊

干什么用的

可以在\(O(\frac{n^{\frac 34}}{\log n})\)的时间内求积性函数\(f(x)\)的前缀和。

别问我为什么是这个复杂度

要求\(f(p)\)是一个关于\(p\)的简单多项式,\(f(p^c)\)可以快速计算。

怎么做啊

首先我们需要对每个\(x=\lfloor\frac ni\rfloor\)求出\(\sum_{i=1}^x[i是质数]f(i)\)。

怎么求呢?

先线性筛出\(\sqrt n\)范围内的质数,设\(P_j\)表示从小到大第\(j\)个质数。

设\(g(n,j)=\sum_{i=1}^{n}[i \in P \ or\ \min(p)>P_j]f(i)\)

说人话就是:\(i\)是质数,或者\(i\)的最小质因子大于\(P_j\),把\(1-n\)内满足条件的\(f(i)\)加起来就是\(g(n,j)\)。

这个东西的实际含义是什么呢?可以参考一下埃氏筛法的运行过程。

假设现在有\(n\)个数依次排开,第\(i\)个数是\(f(i)\),根据埃氏筛法的那套理论,每次选出一个质数,然后筛掉它的所有倍数。

会发现\(g(n,j)\)就是运行\(j\)次埃氏筛法后,没被筛掉的所有数之和加上所有的\(f(p)\)。

我们要求的\(\sum_{i=1}^x[i是质数]f(i)\)其实就是\(g(x,|P|)\),其中\(|P|\)是质数集合的大小。

考虑\(g(n,j)\)的转移,分两种情况:

1、\(P_j^2>n\)。此时运行的第\(j\)次已经不会再筛掉任何数了(因为第\(j\)次运行中筛掉的最小的数是\(P_j^2\)),所以此时\(g(n,j)=g(n,j-1)\)。

2、\(P_j^2\le n\)。这时候我们就要考虑哪些数被筛掉了。被筛掉的数一定含有质因子\(P_j\),且除掉\(P_j\)后最小的质因子会大于等于\(P_j\)。考虑减去\(f(P_j)\times g(\frac{n}{P_j},j-1)\),但在\(g(\frac{n}{P_j},j-1)\)中多减去了\(\sum_{i=1}^{j-1}f(P_i)\)这些最小质因子小于\(P_j\)的函数值,所以再把它们加上就好了。

所以总结起来就是:

\[g(n,j)=\begin{cases} g(n,j-1)&P_j^2\gt n\\ g(n,j-1)-f(P_j)[g(\frac{n}{P_j},j-1)-\sum_{i=1}^{j-1}f(P_i)]&P_j^2\le n\end{cases}
\]

关于\(g(n,j)\)的初值问题:\(g(n,0)\)表示所有数的和,也就是把所有数都当作是质数带入\(f(p)\)的那个多项式中算出的结果。

因为最后只要求所有的\(g(x,|P|)\),所以在求的时候数组只开了一维。这样做的复杂度被证明是\(O(\frac{n^{\frac 34}}{\log n})\)的。

以\(f(x)=1\)即求\(n\)以内的质数个数为例:

for (int i=1,j;i<=n;i=j+1){
j=n/(n/i);w[++m]=n/i;
if (w[m]<=Sqr) id1[w[m]]=m;
else id2[n/w[m]]=m;
g[m]=(w[m]-1)%mod;
}
for (int j=1;j<=tot;++j)
for (int i=1;i<=m&&pri[j]*pri[j]<=w[i];++i){
int k=(w[i]/pri[j]<=Sqr)?id1[w[i]/pri[j]]:id2[n/(w[i]/pri[j])];
g[i]=(g[i]-g[k]+j-1)%mod;g[i]=(g[i]+mod)%mod;
}

说了那么多你求出了啥?

现在我们已经对于\(x=\lfloor\frac ni\rfloor\)求出了\(\sum_{i=1}^x[i是质数]f(i)\)。

我们设\(S(n,j)=\sum_{i=1}^n[\min(p)\ge P_j]f(i)\),也就是所有满足最小质因子大于等于\(P_j\)的\(f\)值之和。

那么最终的答案就是\(S(n,1)+f(1)\)。

鉴于质数的答案我们已经算出来了,是\(g(n,j)-\sum_{i=1}^{j-1}f(P_i)\)。(因为要保证最小质因子大于等于\(P_j\)所以要把小于它的质数减掉)

考虑合数。我们枚举这个合数的最小质因子及其出现次数,然后直接乘即可。

\[S(n,j)=g(n,|P|)-\sum_{i=1}^{j-1}f(P_i)+\sum_{k=j}^{P_k^2\le n}\sum_{e=1}^{P_k^{e+1}\le n}S(\frac{n}{P_k^e},k+1)\times f(P_k^e)+f(P_k^{e+1})
\]

然后这个的复杂度也被证明是\(O(\frac{n^{\frac 34}}{\log n})\)的。

举个栗子

loj6053简单的函数

定义积性函数\(f(p^c)=p\oplus c\),求其前\(n\)项和。

会发现除了\(2\)以外的质数都满足\(f(p)=p\oplus 1=p-1\),所以可以分别计算出\(g(x,|P|)=\sum_{i=1}^x[i是质数]i\)以及\(h(x,|P|)=\sum_{i=1}^x[i是质数]1\)。

在处理\(S\)的时候,如果\(j=1\),就说明其中包含\(2\)这个因数,因此把答案\(+2\)即可。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define ll long long
const int N = 1e6+5;
const int mod = 1e9+7;
int Sqr,zhi[N],pri[N],sp[N],tot,m,id1[N],id2[N],g[N],h[N];
ll n,w[N];
void Sieve(int n){
zhi[1]=1;
for (int i=2;i<=n;++i){
if (!zhi[i]) pri[++tot]=i,sp[tot]=(sp[tot-1]+i)%mod;
for (int j=1;i*pri[j]<=n;++j){
zhi[i*pri[j]]=1;
if (i%pri[j]==0) break;
}
}
}
int S(ll x,int y){
if (x<=1||pri[y]>x) return 0;
int k=(x<=Sqr)?id1[x]:id2[n/x];
int res=(1ll*g[k]-h[k]-sp[y-1]+y-1)%mod;res=(res+mod)%mod;
if (y==1) res+=2;
for (int i=y;i<=tot&&1ll*pri[i]*pri[i]<=x;++i){
ll p1=pri[i],p2=1ll*pri[i]*pri[i];
for (int e=1;p2<=x;++e,p1=p2,p2*=pri[i])
(res+=(1ll*S(x/p1,i+1)*(pri[i]^e)%mod+(pri[i]^(e+1)))%mod)%=mod;
}
return res;
}
int main(){
scanf("%lld",&n);
Sqr=sqrt(n);Sieve(Sqr);
for (ll i=1,j;i<=n;i=j+1){
j=n/(n/i);w[++m]=n/i;
if (w[m]<=Sqr) id1[w[m]]=m;
else id2[n/w[m]]=m;
h[m]=(w[m]-1)%mod;
g[m]=((w[m]+2)%mod)*((w[m]-1)%mod)%mod;
if (g[m]&1) g[m]+=mod;g[m]/=2;
}
for (int j=1;j<=tot;++j)
for (int i=1;i<=m&&1ll*pri[j]*pri[j]<=w[i];++i){
int k=(w[i]/pri[j]<=Sqr)?id1[w[i]/pri[j]]:id2[n/(w[i]/pri[j])];
g[i]=(g[i]-1ll*pri[j]*(g[k]-sp[j-1])%mod)%mod;g[i]=(g[i]+mod)%mod;
h[i]=(h[i]-h[k]+j-1)%mod;h[i]=(h[i]+mod)%mod;
}
printf("%d\n",S(n,1)+1);
return 0;
}

Min_25 筛的更多相关文章

  1. 【UOJ448】【集训队作业2018】人类的本质 min_25筛

    题目大意 给你 \(n,m\),求 \[ \sum_{i=1}^n\sum_{x_1,x_2,\ldots,x_m=1}^i\operatorname{lcm}(\gcd(i,x_1),\gcd(i, ...

  2. Min_25 筛 学习笔记

    原文链接https://www.cnblogs.com/zhouzhendong/p/Min-25.html 前置技能 埃氏筛法 整除分块(这里有提到) 本文概要 1. 问题模型 2. Min_25 ...

  3. UOJ188 Sanrd Min_25筛

    传送门 省选之前做数论题会不会有Debuff啊 这道题显然是要求\(1\)到\(x\)中所有数第二大质因子的大小之和,如果不存在第二大质因子就是\(0\) 线性筛似乎可以做,但是\(10^{11}\) ...

  4. 【SPOJ】DIVCNTK min_25筛

    题目大意 给你 \(n,k\),求 \[ S_k(n)=\sum_{i=1}^n\sigma_0(i^k) \] 对 \(2^{64}\) 取模. 题解 一个min_25筛模板题. 令 \(f(n)= ...

  5. 【51NOD1847】奇怪的数学题 min_25筛

    题目描述 记\(sgcd(i,j)\)为\(i,j\)的次大公约数. 给你\(n\),求 \[ \sum_{i=1}^n\sum_{j=1}^n{sgcd(i,j)}^k \] 对\(2^{32}\) ...

  6. 【51NOD1965】奇怪的式子 min_25筛

    题目描述 给你\(n\),求 \[ \prod_{i=1}^n{\sigma_0(i)}^{i+\mu(i)} \] 对\({10}^{12}+39\)取模. \(\sigma_0(i)\)表示约数个 ...

  7. min_25筛

    min_25筛 用来干啥? 考虑一个积性函数\(F(x)\),用来快速计算前缀和\[\sum_{i=1}^nF(i)\] 当然,这个积性函数要满足\(F(x),x\in Prime\)可以用多项式表示 ...

  8. 关于 min_25 筛的入门以及复杂度证明

    min_25 筛是由 min_25 大佬使用后普遍推广的一种新型算法,这个算法能在 \(O({n^{3\over 4}\over log~ n})\) 的复杂度内解决所有的积性函数前缀和求解问题(个人 ...

  9. 51Nod1222 最小公倍数计数 数论 Min_25 筛

    原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1222.html 题意 给定 $a,b$, 求 $$\sum_{n=a}^b \sum_{i=1}^n ...

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

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

随机推荐

  1. 走近SpringBoot

    (博客园不支持MarkDown编辑,看完整版请移步:https://www.zybuluo.com/Allen-llh/note/1199946) 1. (Building a RESTful Web ...

  2. java读取写入文件

    先来看一下java写入文件 public static void readTxt(String value) throws IOException { FileWriter fw = null; tr ...

  3. 验证码处理类:UnCodebase.cs + BauDuAi 读取验证码的值(并非好的解决方案)

    主要功能:变灰,去噪,等提高清晰度等 代码类博客,无需多说,如下: public class UnCodebase { public Bitmap bmpobj; public UnCodebase( ...

  4. vue 首页背景图片加载完成前增加 loading 效果 -- 使用 new Image() 实现

    1. 创建 loading 公用组件 <template> <div class="load-container"> <div class=" ...

  5. run `npm audit fix` to fix them, or `npm audit` for details

    问题 added 246 packages from 681 contributors and audited 382 packages in 17.509s found 13 vulnerabili ...

  6. Mac 启动 ssh 服务

    Mac 本身有 ssh,只是没有默认开启,需要手动开启. 启动 sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist 关闭 su ...

  7. 【JVM.5】类文件结构

    鲁迅曾经说过:代码编译的结构从本地机器码转变为字节码,是存储格式发展的一小步,确是编程语言发展的一大步. 一.无关性的基石 Java设计者在最初就承诺过“In the future, we will ...

  8. jQuery生成QRcode二维码

    jQuery生成QRcode二维码示例 <!DOCTYPE html> <html> <head> <meta charset="utf-8&quo ...

  9. ubuntu系统升级和其他相关操作记录

    之前在openstack中安装了ubuntu 12.04虚拟机,版本较低,需要升级为高版本.下面分享下升级过程: ubuntu系统升级操作:$ cat /etc/issueUbuntu 12.04.5 ...

  10. Linux系统入门教程:如何在 Linux 中修改默认的 Java 版本

    提问:当我尝试在Linux中运行一个Java程序时,我遇到了一个错误.看上去像程序编译所使用的Java版本与我本地的不同.我该如何在Linux上切换默认的Java版本? 当Java程序编译时,编译环境 ...