[模板]杜教筛

用途

比线性更快($O(n^{\frac{2}{3}})$)地求积性函数的前缀和

前置知识:狄利克雷卷积

形如$h(n)=\sum\limits_{d|n}f(d)g(\frac{n}{d})$,则称$h(n)=f(x)*g(x)$

如果f和g都是积性函数,则卷出的h也是积性函数

可以证明,狄利克雷卷积满足交换律、结合律、分配律

比较重要的卷积式子(抄的..):

$$\mu*1=\varepsilon , \varepsilon(n)=[n=1]$$

$$\varphi*1=id , id(n)=n $$

$$id*\mu=\varphi$$

$$id*1=\sigma , \sigma表示因数和$$

做法

设要求的是$\sum{f(i)}$

构造积性函数$h,g$,使得$h=g*f$,而且需要容易求出$h$和$g$的前缀和

推式子:设S(n)是f的前缀和(以下不是整除的都向下取整)

$$\sum\limits_{i=1}^{n}h(i)=\sum\limits_{i=1}^{n}\sum\limits_{d|i}g(d)f(\frac{n}{d})$$

$$\sum\limits_{i=1}^{n}h(i)=\sum\limits_{d=1}^{n}g(d)\sum\limits_{i=1}^{\frac{n}{d}}f(i)$$

$$\sum\limits_{i=1}^{n}h(i)=\sum\limits_{d=1}^{n}g(d)S(\frac{n}{d})$$

$$把后面的第一项提出来,\sum\limits_{i=1}^{n}h(i)=g(1)S(n)+\sum\limits_{d=2}^{n}g(d)S(\frac{n}{d})$$

$$g(1)S(n)=\sum\limits_{i=1}^{n}h(i)-\sum\limits_{d=2}^{n}g(d)S(\frac{n}{d})$$

于是就可以整除分块,然后递归地求S了(需要先手动求出比较小范围内的S)

需要记忆化,不想带log的话可以用unordered_map(c++11或者tr1/unordered_map)或者手写hash

而且一开始求的那些S不要放到map里,单开一个数组存,不然常数会很大

所以主要是构造比较难构造,看着上面的卷积式瞎怼吧...

例题

bzoj4916 神犇和蒟蒻

注意到$\varphi (i^2) = i\varphi(i)$

然后构造$g=id , h=id^2$即可

 1 #include<bits/stdc++.h>
 2 #include<tr1/unordered_map>
 3 #define CLR(a,x) memset(a,x,sizeof(a))
 4 #define MP make_pair
 5 using namespace std;
 6 typedef long long ll;
 7 typedef unsigned long long ull;
 8 typedef pair<int,int> pa;
 9 const int maxn=1e5+10,P=1e9+7,inv6=166666668;
10
11 inline ll rd(){
12     ll x=0;char c=getchar();int neg=1;
13     while(c<‘0‘||c>‘9‘){if(c==‘-‘) neg=-1;c=getchar();}
14     while(c>=‘0‘&&c<=‘9‘) x=x*10+c-‘0‘,c=getchar();
15     return x*neg;
16 }
17
18 int N,phi[maxn],pri[maxn],cnt;
19 bool np[maxn];
20 tr1::unordered_map<int,int> sum;
21
22 inline int calc(int n){
23     if(sum.count(n)) return sum[n];
24     ll re=0;
25     re=1ll*n*(n+1)%P*(2*n+1)%P*inv6%P;
26     for(int i=2,j;i<=n;i=j+1){
27         j=n/(n/i);
28         re=(re-1ll*(j-i+1)*(j+i)/2%P*calc(n/i))%P;
29     }
30     sum[n]=re;
31     return re;
32 }
33
34 int main(){
35     //freopen("","r",stdin);
36     int i,j,k;
37     phi[1]=1;
38     for(i=2;i<=1e5;i++){
39         if(!np[i]){
40             pri[++cnt]=i;
41             phi[i]=i-1;
42         }for(j=1;j<=cnt&&pri[j]*i<=1e5;j++){
43             np[i*pri[j]]=1;
44             if(i%pri[j]==0){
45                 phi[i*pri[j]]=phi[i]*pri[j];
46                 break;
47             }
48             phi[i*pri[j]]=phi[i]*phi[pri[j]];
49         }
50     }
51     sum[0]=0;
52     for(i=1;i<=1e5;i++){
53         sum[i]=(sum[i-1]+1ll*i*phi[i])%P;
54     }
55     printf("1\n%d\n",(calc(rd())+P)%P);
56     return 0;
57 }

原文地址:https://www.cnblogs.com/Ressed/p/10228376.html

时间: 2024-10-09 07:21:13

[模板]杜教筛的相关文章

luoguP4213 [模板]杜教筛

https://www.luogu.org/problemnew/show/P4213 同 bzoj3944 考虑用杜教筛求出莫比乌斯函数前缀和,第二问随便过,第一问用莫比乌斯反演来做,中间的整除分块里的莫比乌斯前缀和刚好用第二问来做 杜教筛的时候先线性筛出前 N 个数的莫比乌斯函数前缀和,其余的用 map 记忆化搜索,实测 N 取 3670000 最佳(其实我只测了3次) #include <bits/stdc++.h> using namespace std; typedef unsign

P4213 【模板】杜教筛(Sum)

\(\color{#0066ff}{题 目 描 述}\) 给定一个正整数\(N(N\le2^{31}-1)\) 求 \(\begin{aligned} ans_1=\sum_{i=1}^n\varphi(i) \end{aligned}\) \(\begin{aligned} ans_2=\sum_{i=1}^n \mu(i) \end{aligned}\) \(\color{#0066ff}{输 入 格 式}\) 一共T+1行 第1行为数据组数T(T<=10) 第2~T+1行每行一个非负整数N

【模板】杜教筛(Sum)

传送门 Description 给定一个正整数\(N(N\le2^{31}-1)\) 求 \[ans1=\sum_{i=1}^n \varphi(i)\] \[ans_2=\sum_{i=1}^n \mu(i)\] Solution 总算是写了一个不会\(TLE\)的杜教筛,不想用\(map\),因此上了一个很丑的\(Hash\)-- Code #include<bits/stdc++.h> #define ll long long #define max(a,b) ((a)>(b)?(

[模板][P3377]杜教筛

Description: 求 $ \sum_{i=1}^n \phi(i) ,\sum_{i=1}^n \mu(i)$ Hint: \(n<=10^{10}?\) Solution: 考虑积性函数 \(f,g,h?\) 及其前缀和 \(F,G,H?\) 其中 \(h=f*g?\) 首先 \(H(x)=\sum_{n=1}^xh(n)\) \(=\sum_{n=1}^x \sum_{d|n} f(d) g(\frac{n}{d})\) 枚举倍数转枚举因数 \(=\sum_{k=1}^x \sum_

P4213【模板】杜教筛(Sum)

思路:杜教筛 提交:\(2\)次 错因:\(\varphi(i)\)的前缀和用\(int\)存的 题解: 对于一类筛积性函数前缀和的问题,杜教筛可以以低于线性的时间复杂度来解决问题. 先要构造\(h=f*g\),并且\(h\)的前缀和易求,\(g\)的区间和易求. 具体地: \[\sum_{i=1}^{n}h(i)=\sum_{i=1}^{n}\sum_{d|i}g(d)\cdot f(\frac{i}{d})\] \[\sum_{i=1}^{n}h(i)=\sum_{d=1}^{n}g(d)\

CCPC 2019 网络赛 HDU huntian oy (杜教筛)

1005 huntian oy (HDU 6706) 题意: 令,有T次询问,求 f(n, a, b). 其中 T = 10^4,1 <= n,a,b <= 1e9,保证每次 a,b互质. 思路: 首先我们需要知道 公式: gcd(a^n - b^n, a^m - b^m) = a^(gcd(m,n)) - b^(gcd(m,n)) 由a,b互质,原式即为 f(n, a, b) = ∑∑ (i-j)*[(i,j)=1] = ∑ (i*∑ [(i, j)=1] ) - ∑∑ j*[(i, j)=

【数论】狄利克雷卷积及其快速计算方法及杜教筛

目录(假的 狄利克雷卷积基础知识 数论函数 狄利克雷卷积定义 狄利克雷卷积性质 常用卷积 卷积计算方法 最暴力的暴力 稍好的暴力 优美的暴力 莫比乌斯反演(待填坑) 杜教筛 经典杜教筛 第二种杜教筛 第三种杜教筛 背景 本人即将去CTS&APIO2019,由于一些特殊原因,发现自己数论突然变得很菜. 就决定在去的前一天,翻出来以前的数论学习资料看一看.翻到了czgj的校内狄利克雷卷积课件,发现其中提到了的任意数列\(f(n)\)和\(g(n)\)的狄利克雷卷积\((f*g)(n)\)(从1到n,

【bzoj 4176】 Lucas的数论 莫比乌斯反演(杜教筛)

Description 去年的Lucas非常喜欢数论题,但是一年以后的Lucas却不那么喜欢了. 在整理以前的试题时,发现了这样一道题目“求Sigma(f(i)),其中1<=i<=N”,其中 表示i的约数个数.他现在长大了,题目也变难了. 求如下表达式的值: 一行一个整数ans,表示答案模1000000007的值. Sample Input 2 Sample Output 8 HINT 对于100%的数据n <= 10^9. 题解: 解锁新技能:杜教筛. 再复习一下: 若$F(n)=\s

【51nod-1239&amp;1244】欧拉函数之和&amp;莫比乌斯函数之和 杜教筛

题目链接: 1239:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1239 1244:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1244 杜教筛裸题,不过现在我也只会筛这俩前缀和... $$s(n)=\sum _{i=1}^{n}f(i)$$ 那么就有: $$\sum_{i=1}^{n}f(i)\lfloor \frac{n}{i} \