Min_25 筛与杜教筛
杜教筛
\(\) 是 \(\) 的前缀和,\(\), \(\) 同理。
假设 \( × = ℎ\) ,并且 \(, \) 易求出,\(\) 难求出。
那么
(\frac {} {})\\
= f(1)\cdot () + \sum_{2≤≤} () (\frac {} {})\]
有:
\]
整除分块,可以在 \(O(n^{\frac {3}{4}})\) 的时间内计算出 \((n)\)
代码按照理解大概可以写成这样:
ll GetSum(int n){
ll ans = H(n);
for(ll l = 2, r; l <= n; l = r + 1) {
r = (n / (n / l));
ans -= (F(r) - F(l - 1)) * GetSum(n / l);
} return ans;
}
时间复杂度证明:
考虑到求 \(S(n)\) 时,需要求出 \(2 \times \sqrt n\) 个 \(S(\lfloor \frac {n}{i} \rfloor)\) 。
由于 \(\lfloor \frac{\lfloor \frac {n}{a}\rfloor}{b} \rfloor =\lfloor \frac {n}{a b} \rfloor\) ,显然所需要求的 \(S(\lfloor \frac {n}{i} \rfloor)\) 数量只有 \(2 \times \sqrt n\) 个。
考虑到整除分块的复杂度,可得总复杂度为:
\]
还可以进一步优化杜教筛,即先线性筛出前 \(m\) 个答案,之后再用杜教筛。
这个优化之后的复杂度是:
\]
取 \(m=n^{\frac {2}{3}}\) 时,总复杂度为 \(O(n^{\frac {2}{3}})\)
此时预处理复杂度与筛法复杂度相等,为杜教筛的最优复杂度。
杜教筛小应用
比如说我们要求 \(g()=()\times \) 的前缀和
那么观察 \( * = ^2\) ,就令 \( = \),\(ℎ = ^2\) 即可。
比如说我们要求 \(g()= () \times ^\) 的前缀和
那么观察 \( * ^ = ^{+1}\) ,就令 \( = ^\),\(ℎ = ^{+1}\) 即可。
比如说我们要求 \(g () = () \times ^\) 的前缀和
那么观察 \( * ^ = ^∗ = \),就令 \( = ^\),ℎ = 即可。
例题:
【模板】杜教筛(Sum)
求 \(\sum_{i=0}^{n} \mu(i)\) :
发现 \(\mu * I = e\)
有:
\]
\]
\]
求 \(\sum_{i=0}^{n} \varphi (i)\):
发现 \(\varphi * I = id\)
有:
\]
\]
\]
点击查看代码
P3768 简单的数学题
求:
\]
枚举 \(gcd\) :
\]
\]
\]
\]
\]
\]
[NOI2016] 循环之美
求:
\]
拆 \([i\perp j]\) ,得:
=\sum_{i=1}^{n}\sum_{j=1}^{m}\sum_{t|i,t|j}\mu(t)[j\perp k]\\
=\sum_{t|j}\mu(t)\sum_{t|i}^{n}\sum_{j=1}^{m}[j\perp k]\\
=\sum_{t}\mu(t)\lfloor\frac{n}{t}\rfloor \sum_{t|j}^{m}[j\perp k]\\
=\sum_{t}\mu(t)\lfloor\frac{n}{t}\rfloor \sum_{j=1}^{\lfloor\frac{m}{t}\rfloor}[tj\perp k]\\
=\sum_{t}\mu(t)\lfloor\frac{n}{t}\rfloor \sum_{j=1}^{\lfloor\frac{m}{t}\rfloor}[t\perp k][j\perp k]\\
=\sum_{t}\mu(t)\lfloor\frac{n}{t}\rfloor[t\perp k] \sum_{j=1}^{\lfloor\frac{m}{t}\rfloor}[j\perp k]\\
\]
记 \(g(x)=\sum_{i=1}^x\limits\ [i\perp k]\) ,发现 \(g(x)=\lfloor\dfrac{x}{k} \rfloor\varphi(k)+g(x\bmod k)\) ,可以 \(O(k)\) 预处理 ,\(O(1)\) 查询。
变为:
\]
对于式子的前两项可以整除分块,需要快速求 \(\mu(t)[t\perp k]\) 的前缀和。
令 \(f(n)=\sum_{i=1}^n\limits \mu(i)[i\perp k]\) ,有:
\]
发现 :
=\sum_{i=1}^{n}\sum_{j=1}^{\lfloor\frac{n}{i}\rfloor}\mu(j)[ij\perp k]\\
=\sum_{t=1}^n[t\perp k]\sum_{d|t}\mu(d)\\
=\sum_{t=1}^n[t\perp k][t==1]\\
=1
\]
进而:
\]
发现 \(g(n)=\sum_{i=1}^n\limits [i\perp k]\) 前面已经可以 \(O(1)\) 求出,杜教筛即可。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n,m,k;
const int lim=1e7;
int pri[10000005],top,mu[10000005],g[1005],f[10000005],phi[10000005];
bool vis[10000005];
int gcd(int x,int y){
return y?gcd(y,x%y):x;
}
inline void init(){
mu[1]=g[1]=f[1]=1;
for(int i=2;i<=lim;i++){
if(!vis[i])pri[++top]=i,mu[i]=-1,phi[i]=i-1;
if(i<k)g[i]=g[i-1]+(gcd(i,k)==1);
f[i]=f[i-1]+(gcd(i,k)==1)*mu[i];
for(int j=1;j<=top&&i*pri[j]<=lim;j++){
vis[i*pri[j]]=1;
if(i%pri[j]==0){
phi[i*pri[j]]=phi[i]*pri[j];break;
}
mu[i*pri[j]]=-mu[i];phi[i*pri[j]]=phi[i]*phi[pri[j]];
}
}
}
inline long long G(int x){
return 1ll*x/k*phi[k]+g[x%k];
}
map<int,long long> mp;
inline long long F(int x){
if(x<=lim)return f[x];
if(mp.count(x))return mp[x];
long long res=1;
for(int l=2,r;l<=x;l=r+1){
r=x/(x/l);
res-=(G(r)-G(l-1))*F(x/l);
}return mp[x]=res;
}
inline void solve(){
long long res=0;
for(int l=1,r;l<=n&&l<=m;l=r+1){
r=min(n/(n/l),m/(m/l));
res+=(F(r)-F(l-1))*G(m/l)*(n/l);
}
printf("%lld",res);
}
int main(){
scanf("%d%d%d",&n,&m,&k);
init();solve();
return 0;
}
SCZ 2022-3-17 密码
求 :
\]
有:
\]
进而:
=\sum_{i=1}^n\sum_{j=1}^m \sum_{x|i}\sum_{y|j}\sum_{d|x,d|y}\mu(d)(\frac{i}{x}\cdot y)^k\\
=\sum_{i=1}^n\sum_{x|i}(\frac{i}{x})^k\sum_{j=1}^m \sum_{y|j}(y)^k\sum_{d|x,d|y}\mu(d)\\
=\sum_{d}\mu(d)\sum_{i=1}^n\sum_{d|x,x|i}(\frac{i}{x})^k\sum_{j=1}^m \sum_{d|y,y|j}(y)^k\\
=\sum_{d}\mu(d)d^k\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sigma_k(i)\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}\sigma_k(j)
\]
考虑构造 \(\sigma_k\) 和 \(\mu\cdot id^k\) 的杜教筛。
发现 \(\sigma_k*\mu=id^k\) ,有:
\]
要筛 \(\mu\) 的前缀和:
\]
再看 \(\mu\cdot id^k\) ,发现 \((\mu\cdot id^k)*id^k=1\) ,因此:
\]
其中自然数 \(k\) 次幂前缀和是 \(k+1\) 次多项式,可以拉格朗日插值或高斯消元求出。其余部分杜教筛即可。
点击查看代码
Min_25 筛
对于满足一下条件的积性函数 \(\) ,如果其满足一下两条件,那么可以快速计算 \(\) :
\( ()\) 是关于 \(\) 的低阶多项式。
\((^)\) 有快速计算的方法。
比如 \( () = − 1\),\( (^) = ( − 1) ^{−1} = (^{−1})∗ \)
时间复杂度为 \(O(\frac{n^{\frac{3}{4}}}{log\ n})\),空间复杂度为 \(O(\sqrt n)\)
step 1:
对于每一个 \(x=\lfloor \frac{n}{i} \rfloor\),求出:
\]
令:
\]
其中 \(div(j)\) 表示 \(j\) 的最小质因子。
\(G(n,i)\) 即为 \(≤n\) 且在埃氏筛第 \(i\) 轮后未被筛去的数的 \(k\) 次方和。
一个合数 \(x\ (x≤n)\) ,一定含有 \(≤\sqrt n\) 的质因子,因此若令 \(cnt\) 表示 \(≤n\) 的质数个数,\(G(n,cnt)\) 即为所求。
考虑递推求 \(G(n,i)\):
若 \(pri_i^2>n\) ,则第 \(i\) 轮不会删除任何数 ,有 \(G(n,i)=G(n,i-1)\)
若 \(pri_i^2≤n\),则第 \(i\) 轮会删除的数的 \(k\) 次方和即为 \(pri_i^k\times (G(\lfloor \frac {n}{pri_i} \rfloor,i-1)-\sum_{j=1}^{i-1}\limits pri_j^k)\)
因此,有:
\ \sum_{j=1}^{n}\limits j^k
\\
G(n,i-1)
\\
G(n,i-1)-pri_i^k\times (G(\lfloor \frac {n}{pri_i} \rfloor,i-1)-\sum_{j=1}^{i-1}\limits pri_j^k)
\end{cases}\ \ \
\begin{matrix}
(i=0)
\\
(pri_i^2>n)
\\
(pri_i^2≤n)
\end{matrix}
\]
在储存时,由于 \(\lfloor \frac{n}{i} \rfloor\) 的种类数不超过 \(2\times \sqrt n\) 种
因此可以开两个数组 \(ind1,ind2\) 将这 \(2\times \sqrt n\) 个数离散化,若 \(\lfloor \frac{n}{i} \rfloor ≤ \sqrt n\) 则将其存在 \(ind1[\lfloor \frac{n}{i} \rfloor]\) 处,否则将其存在 \(ind2[\lfloor \frac{n}{\lfloor \frac{n}{i} \rfloor} \rfloor]\) 处。
最终可以递推出 \(G(n,cnt)\) ,代码大致如下:
ll r=0;
for(ll l = 1; l <= n; l = r + 1) {
r = n / (n / l); w[++tot]= n / l;
g[tot] = n / l;
g[tot] = (g[tot] * (g[tot] + 1) * inv2 - 1);
if( n / l <= B ) ind1[n / l] = tot;
else ind2[n / (n / l)] = tot;
}
for(int i = 1; i <= top; i++) {
for(int j = 1; j <= tot && pri[i] * pri[i] <= w[j]; j++) {
int k = w[j] / pri[i] <= B ? ind1[w[j] / pri[i]] : ind2[n / (w[j] / pri[i])];
g[j] = (g[j] - pri[i] * (g[k] - sum[i - 1]));
}
}
step 2:
定义 \(S(n,i)=\sum_{j=1}^{n}[div(j)>=pri_i]\cdot f(j)\),显然,最后答案就是 \(S(n,1)+f(1)\) 。
其中,对于 \(S(n,i)\) 质数的贡献为 \(\sum_{k}\limits G^k(n)\cdot [x^k]f(i)-\sum_{j=1}^{i-1}\limits pri_j\)
对于合数,我们枚举它的最小质因子,以及最小质因子的幂次,贡献为 \(\sum_{j=i}^{pri_j^e≤n}\limits f(pri_j^e)\cdot (S(\lfloor \frac{n}{pri_i^e} \rfloor,j+1)+[e!=1])\)
因此,有:
0
\\
\sum_{k}\limits G^k(n)\cdot [x^k]f(i)-\sum_{j=1}^{i-1}\limits pri_j-\sum_{j=i}^{pri_j^e≤n}\limits f(pri_j^e)\cdot (S(\lfloor \frac{n}{pri_i^e} \rfloor,j+1)+[e!=1])\end{cases}\ \ \ \begin{matrix}(pri_i>n)\\(pri_i≤n)\end{matrix}
\]
简计:
(pri_i≤n)\end{matrix}
\]
ll S(ll x,int i){
if( pri[i] > x ) return 0;
int k = ( x <= B ? ind1[x] : ind2[n / x] );
ll res = g[k] - sum[i-1];
for(int j = i; j <= top && pri[j] * pri[j] <= x; j ++ ){
ll P = pri[j];
for(ll t = 1; P * pri[j] <= x; t ++ , P *= pri[j] ){
ll Pw = P;
res = res + Pw * S(x / P,j + 1);
res = res + Pw * pri[j];
}
}return res;
}
时间复杂度 \(O(\frac{n^{\frac{3}{4}}}{log\ n})\) 或 \(O(n^{1-ϵ})\) ,不需要记忆化。
例题:
【模板】Min_25筛
模板题
点击查看代码
```cpp
```
#6235. 区间素数个数
点击查看代码
```cpp
```
SCZ 2022-2-18 取数
对于正整数 \(x =∏_{1≤i≤m}\limits p^{s_i}_i\) ,其中 \(p_i\) 为质数,\(p_i < p_{i+1}\),\(s_i > 0\)。
令序列 \(A\) 为 \(A_i = p^{s_i}_i + s^{p_i}_i\) 。
设 \(f(x) = ∑_P\limits ∏A_i[i ∈ P]\),其中 \(P\) 为 \(i|1 ≤ i ≤ m\) 的非空子集,且 \(P\) 中不包含相邻的元素,即 \(i\) 和 \(i + 1\) 不同时属于 \(P\)。
求 \(∑^n_{i=2}\limits f(x)\) 对 \(P\) 取模的结果。
发现对于单个数 \(x\) 可以通过 \(dp\) 求出 \(f(x)\) 的值,而且是积性函数,可以转换成矩阵做 \(Min_25\) ,也可以开结构体直接做。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int lim;
ll n,md;
struct mat{
ll tmp0,tmp1;
mat(){
tmp0=0;tmp1=0;
}
mat(ll _x,ll _y){
tmp0=_x%md;tmp1=_y%md;
}
inline mat operator *(mat b){
return mat((b.tmp0+b.tmp1)%md*tmp0%md,b.tmp0*tmp1%md);
}
inline mat operator +(mat b){
return mat((tmp0+b.tmp0)%md,(tmp1+b.tmp1)%md);
}
inline mat operator -(mat b){
return mat((tmp0-b.tmp0+md)%md,(tmp1-b.tmp1+md)%md);
}
};
int pri[100005],top;
bool vis[100005];
int ind1[100005],ind2[100005],cnt;
ll w[200005],g0[200005],g1[200005],sum[100005];
inline void Init(){
for(int i=2;i<=lim;i++){
if(!vis[i])pri[++top]=i,sum[top]=(sum[top-1]+i)%md;
for(int j=1;j<=top&&1ll*i*pri[j]<=lim;j++){
vis[i*pri[j]]=1;
if(i%pri[j]==0)break;
}
}
for(ll l=1,r;l<=n;l=r+1){
r=n/(n/l);w[++cnt]=n/l;
g0[cnt]=(w[cnt]-1)%md;g1[cnt]=((w[cnt]+1)%md*(w[cnt]%md)/2-1)%md;
if(w[cnt]<=lim)ind1[w[cnt]]=cnt;
else ind2[n/w[cnt]]=cnt;
}
for(int i=1;i<=top;i++){
for(int j=1;j<=cnt&&1ll*pri[i]*pri[i]<=w[j];j++){
ll k=w[j]/pri[i]<=lim?ind1[w[j]/pri[i]]:ind2[n/(w[j]/pri[i])];
g0[j]=((g0[j]-(g0[k]-i+1))%md+md)%md;
g1[j]=((g1[j]-pri[i]*(g1[k]-sum[i-1]))%md+md)%md;
}
}
}
inline ll pwr(ll x,ll y){
ll res=1;
while(y){
if(y&1)res=res*x%md;
x=x*x%md;y>>=1;
}
return res;
}
mat Min_25(ll x,int i){
if(x<=1||pri[i]>x)return mat();
int k=x<=lim?ind1[x]:ind2[n/x];
mat res=mat(g0[k],(g1[k]+g0[k])%md)-mat(i-1,(sum[i-1]+i-1)%md);
for(int j=i;j<=top&&1ll*pri[j]*pri[j]<=x;j++){
ll P=pri[j];
for(int e=1;P*pri[j]<=x;e++,P*=pri[j]){
res=res+mat(1,(P+pwr(e,pri[j]))%md)*Min_25(x/P,j+1);
res=res+mat(1,(P*pri[j]%md+pwr(e+1,pri[j]))%md);
}
}
return res;
}
int main(){
scanf("%lld%lld",&n,&md);lim=sqrt(n)+1;
Init();
mat res=Min_25(n,1);
printf("%lld\n",((res.tmp0+res.tmp1-n+1)%md+md)%md);
return 0;
}
#6053. 简单的函数
点击查看代码
```cpp
```
#188. 【UR #13】Sanrd
点击查看代码
```
</details>
Min_25 筛与杜教筛的更多相关文章
- 【知识总结】线性筛_杜教筛_Min25筛
首先感谢又强又嘴又可爱脸还筋道的国家集训队(Upd: WC2019 进候选队,CTS2019 不幸 rk6 退队)神仙瓜 ( jumpmelon ) 给我讲解这三种筛法~~ 由于博主的鸽子属性,这篇博 ...
- 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\) 的次大质 ...
- P4213 【模板】杜教筛(杜教筛)题解
题意: 求\(\sum_{i=1}^n\varphi(i)\)和\(\sum_{i=1}^n\mu(i)\) 思路: 由性质可知:\(\mu*I=\epsilon,\varphi*I=id\)那么可得 ...
- 【LOJ#572】Misaka Network 与求和(莫比乌斯反演,杜教筛,min_25筛)
[LOJ#572]Misaka Network 与求和(莫比乌斯反演,杜教筛,min_25筛) 题面 LOJ \[ans=\sum_{i=1}^n\sum_{j=1}^n f(gcd(i,j))^k\ ...
- 杜教筛 && bzoj3944 Sum
Description Input 一共T+1行 第1行为数据组数T(T<=10) 第2~T+1行每行一个非负整数N,代表一组询问 Output 一共T行,每行两个用空格分隔的数ans1,ans ...
- hihocoder #1456 : Rikka with Lattice(杜教筛)
hihocoder #1456 : Rikka with Lattice(杜教筛) 题意 : 给你一个\(n*m\)方格图,统计上面有多少个格点三角形,除了三个顶点,不覆盖其他的格点(包括边和内部). ...
- BZOJ3944: Sum(杜教筛模板)
BZOJ3944: Sum(杜教筛模板) 题面描述 传送门 题目分析 求\(\sum_{i=1}^{n}\mu(i)\)和\(\sum_{i=1}^{n}\varphi(i)\) 数据范围线性不可做. ...
- [BZOJ3944]Sum(杜教筛)
3944: Sum Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 6201 Solved: 1606[Submit][Status][Discuss ...
- luoguP4213 【模板】杜教筛(Sum)杜教筛
链接 luogu 思路 为了做hdu来学杜教筛. 杜教筛模板题. 卡常数,我加了register居然跑到不到800ms. 太深了. 代码 // luogu-judger-enable-o2 #incl ...
随机推荐
- Vue.js Mixins 混入使用
Mixins一般有两种用途: 1.在你已经写好了构造器后,需要增加方法或者临时的活动时使用的方法,这时用混入会减少源代码的污染. 2.很多地方都会用到的公用方法,用混入的方法可以减少代码量,实现代码重 ...
- 用python爬虫,对12306网站进行模拟登陆
from selenium import webdriver from time import sleep from PIL import Image from selenium.webdriver ...
- k8s client-go源码分析 informer源码分析(1)-概要分析
k8s informer概述 我们都知道可以使用k8s的Clientset来获取所有的原生资源对象,那么怎么能持续的获取集群的所有资源对象,或监听集群的资源对象数据的变化呢?这里不需要轮询去不断执行L ...
- Go学习-基本语法(一)
前言 一直对Service Mesh相关内容比较感兴趣,后面一路学习了Dcoker.Kubernetes等相关内容,可以说是对基本概念和使用有一定了解,随着开始学习一些相关的组件的时候,发现基本上全部 ...
- react实战系列 —— 我的仪表盘(bizcharts、antd、moment)
其他章节请看: react实战 系列 My Dashboard 上一篇我们在 spug 项目中模仿"任务计划"模块实现一个类似的一级导航页面("My任务计划") ...
- 用更云原生的方式做诊断|大规模 K8s 集群诊断利器深度解析
背景 通常而言,集群的稳定性决定了一个平台的服务质量以及对外口碑,当一个平台管理了相当规模数量的 Kubernetes 集群之后,在稳定性这件事上也许会"稍显被动". 我们可能经常 ...
- Cocos---监听、触摸事件、坐标系转换
监听.触摸事件.坐标系转换 Creator的系统事件 分为"节点系统事件"和"全局系统事件". 节点系统事件:触发在节点上,包括鼠标事件和触摸事件. 全局系统事 ...
- 【freertos】008-内存管理
前言 本章主要讲解内部存储空间(RAM)的管理. 详细分析heap5方案. 参考: 李柱明博客 https://freertos.blog.csdn.net/article/details/51606 ...
- 【leetcode】42. 接雨水
目录 题目 题解 题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水. 示例 1: 输入:height = [0,1,0,2,1,0,1,3,2,1 ...
- 浅析kubernetes中client-go structure01
Prepare Introduction 从2016年8月起,Kubernetes官方提取了与Kubernetes相关的核心源代码,形成了一个独立的项目,即client-go,作为官方提供的go客户端 ...