杜教筛

求积性函数前缀和

有一些重要且基本的积性函数:

\(\epsilon\), 满足

\[\epsilon(n) = [n = 1] \]

\(1\), 满足

\[1(n) = 1 \]

\(id\), 满足

\[id(n) = n \]

狄利克雷卷积:

\[(f\ast g)(n) = \sum\limits_{d|n}f(d)g(\frac{n}{d}) \]

得到以下式子:

\[\mu\ast 1 = \epsilon \]

\[\varphi\ast 1= id \]

进入正题:

有积性函数\(f\),求\(f(1)+...+f(n)\)的和

\[S(i)=\sum_{i=1}^{n} f(i) \]

要求的答案就是\(S(i)\)

先对于任意一个积性函数\(g\),求它与\(f\)卷积的和,

理解意义,\(f(d)g(\frac{i}{d})\) 即枚举 \(i\) ,算因数的贡献

\[\sum_{i=1}^{n}\sum_{d|i}f(d)g(\frac{i}{d}) \]

这里变换枚举顺序,乘积为 \(i\ast d (\leq n)\),即枚举因数,对乘积的贡献

\[=\sum_{i=1}^{n}\sum_{d=1}^{\lfloor \frac{n}{i} \rfloor}g(i)f(d) \]

提出\(g(i)\)

\[=\sum_{i=1}^{n}g(i)\sum_{d=1}^{\lfloor \frac{n}{i} \rfloor}f(d) \]

后面的和式替换成上面定义的\(S(i)\)

\[=\sum_{i=1}^{n}g(i)S(\lfloor \frac{n}{i} \rfloor) \]

一开始的式子和解出的式子

\[\sum_{i=1}^{n}\sum_{d|i}f(d)g(\frac{i}{d}) = \sum_{i=1}^{n}g(i)S(\lfloor \frac{n}{i} \rfloor) \]

分裂右边

\[\sum_{i=1}^{n}\sum_{d|i}f(d)g(\frac{i}{d}) = g(1)S(n) + \sum_{i=2}^{n}g(i)S(\lfloor \frac{n}{i} \rfloor) \]

移项得

\[g(1)S(n) = \sum_{i=1}^{n}\sum_{d|i}f(d)g(\frac{i}{d}) - \sum_{i=2}^{n}g(i)S(\lfloor \frac{n}{i} \rfloor) \]

右边\(S\)的取值有\(\lfloor \frac{n}{i} \rfloor\)种,用整除分块求出,时间\(O(\sqrt n)\)

\(\\\)
\(\\\)

\[\sum_{i = 1}^{n}\mu(i) \]

\(\mu\)当成\(f\),把\(1\)当成\(g\),代入上上面的式子中,即:

\[1(1)S(n) = \sum_{i=1}^{n}\sum_{d|i}\mu(d)1(\frac{i}{d}) - \sum_{i=2}^{n}1(i)S(\lfloor \frac{n}{i} \rfloor) \]

开头有个式子:

因为

\[\mu\ast 1 = \epsilon \]

\[\sum_{d|n}\mu(d)1(\frac{n}{d}) = \epsilon(n) \]

所以

\[1(1)S(n) = \sum_{i=1}^{n}\epsilon(i) - \sum_{i=2}^{n}1(i)S(\lfloor \frac{n}{i} \rfloor) \]

因为\(1,\epsilon\)的定义,可得

\[1 * S(n) = \sum_{i=1}^{n}[i = 1] - \sum_{i=2}^{n}1 * S(\lfloor \frac{n}{i} \rfloor) \]

\[S(n) = 1 - \sum_{i=2}^{n}S(\lfloor \frac{n}{i} \rfloor) \]

注意,这里的下标从\(2\)开始

\(\\\)
\(\\\)

\[\sum_{i=1}^{n} = \varphi(i) \]

同上,\(\varphi\)代替\(f\),\(1\)代替\(g\)

\[1(1)S(n) = \sum_{i=1}^{n}\sum_{d|i}\varphi(d)1(\frac{i}{d}) - \sum_{i=2}^{n}1(i)S(\lfloor \frac{n}{i} \rfloor) \]

因为

\[\varphi\ast 1= id \]

\[1(1)S(n) = \sum_{i=1}^{n}id(i) - \sum_{i=2}^{n}1(i)S(\lfloor \frac{n}{i} \rfloor) \]

\[S(n) = \sum_{i=1}^{n}id(i) - \sum_{i=2}^{n}S(\lfloor \frac{n}{i} \rfloor) \]

\(id(n) = n\)可得,

\[S(n) = \frac{(1+n)n}{2} - \sum_{i=2}^{n}S(\lfloor \frac{n}{i} \rfloor) \]

LuoguP4213 【模板】杜教筛(Sum)
\(\mu,\varphi\)的和的代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int T;

unordered_map<int, int> Mu;
unordered_map<int, ll> Phi;
//基于hash的map,查询期望O(1)

const int MAXN = 10000001;
int len;
int prime[2000000], mu[MAXN];
ll phi[MAXN];
bool isprime[MAXN];

//线性筛预处理1~10^7的phi,mu的和
void pre(){
	int N = MAXN;
//	memset(isprime, 1, sizeof(isprime));卡卡常
	mu[1] = 1;
	phi[1] = 1;
	for(int i = 2; i <= N; i++){
		if (!isprime[i]){
			prime[++len] = i;
			mu[i] = - 1;
			phi[i] =  i - 1;
		}
		for(int j = 1; j <= len && prime[j] * i <= N; j++){
			int k = prime[j] * i;
			isprime[k] = true;
			if (i % prime[j] == 0) {
				phi[k] = phi[i] * prime[j];
                                 //这里可以这样转移,比较特殊,其他的就不一定了
				break;
			}
			phi[k] = phi[prime[j]] * phi[i];
			mu[k] = -mu[i]; 
		}
		
	}
	for(int i = 1; i <= N; i++)
		mu[i] += mu[i - 1],
		phi[i] += phi[i - 1];
}


//递归求解
int MuSum(int n){
	if (n <= MAXN) return mu[n];
	if (Mu.count(n)) return Mu[n];
        //预处理减少时间
	int sum = 0, r;
	for(int l = 2; l <= n; l = r + 1){
		r = n/(n/l);
		sum += MuSum(n/l) * (r - l + 1);
	}
	sum = 1 - sum;
	Mu[n] = sum;
	return sum;
}

ll PhiSum(int n){
	if (n <= MAXN) return phi[n];
	if (Phi.count(n)) return Phi[n];
	ll sum = 0, r;
	for(int l = 2; l <= n; l = r + 1){
		r = n/(n/l);
		sum += PhiSum(n/l) * (r - l + 1);
	}
	sum = 1ll*(1+n)*n/2 - sum;
	Phi[n] = sum;
	return sum;
}
int main(){
	pre();
	scanf("%d", &T);
	while(T--){
		int n;
		scanf("%d", &n);
		ll ans1 = PhiSum(n);int ans2 = MuSum(n);
		printf("%lld %d\n",ans1,ans2);
	}
	return 0;
}
posted @ 2020-08-17 19:05  qjbqjb  阅读(55)  评论(0编辑  收藏  举报