/* 返回顶部 */

【模板】杜教筛

杜教筛用来解决积性函数前缀和的问题。
复杂度为\(O(n^\frac{2}{3})\)
适用情况:
已知函数\(f\),求\(\sum f\)
存在\(f*g=F\),且\(g,\sum g,F,\sum F\)容易求出。

常用公式:
\(\mu*I=[n=1]\)
\(\varphi*I=id\)

以求\(\sum \mu\)为例。

\[\mu*I=[n=1] \\ \sum_{i = 1}^{n}[i = 1] = 1 \\ 1 = \sum_{i = 1}^{n}[i = 1] \]

构造出所求函数\(\mu\)

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

\(t=i/d\)

\[1 = \sum_{t = 1}^{n} \sum_{d = 1}^{\lfloor \frac{n}{t} \rfloor} \mu(d) \\ \]

\(M(\lfloor \frac{n}{t} \rfloor) = \sum\limits_{d = 1}^{\lfloor \frac{n}{t} \rfloor} \mu(d)\)$

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

对于\(i<10^7\),可以预处理出\(M(i)\)的值,存到数组里。
比较大的数可以通过数论分块递推求解。

模板题:51nod 1244 莫比乌斯函数之和

注意:

  • 空间限制
  • 计算\(f(x)\)时,因为需要递归,不能把\(ans\)开成全局变量!

\(code\)

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define MogeKo qwq
using namespace std;

const int maxn = 1e7+5;
const int mod = 999979;

long long a,b;
int prime[5000005],mu[maxn],M[maxn];
int head[mod],nxt[1000005];
int cnt,tot;
pair <long long,long long> num[1000005];
bool vis[maxn],flag;

void Prime() {
	M[1] = mu[1] = 1;
	for(int i = 2; i <= 10000000; i++) {
		if(!vis[i]) {
			mu[i] = -1;
			prime[++tot] = i;
		}
		for(int j = 1; j <= tot && i*prime[j] <= 10000000; j++) {
			vis[i*prime[j]] = true;
			if(i % prime[j] == 0) break;
			else mu[i*prime[j]] = -mu[i];
		}
		M[i] = M[i-1] + mu[i];
	}
}

void add(long long key,long long val) {
	int x = key % mod;
	num[++cnt] = make_pair(key,val);
	nxt[cnt] = head[x];
	head[x] = cnt;
}

long long query(long long key) {
	int x = key % mod;
	for(int i = head[x]; i; i = nxt[i])
		if(num[i].first == key) {
			flag = true;
			return num[i].second;
		}
	return 0;
}

long long f(long long x) {
	if(x <= 10000000) return M[x];
	flag = false;
	long long ans = query(x);
	if(flag) return ans;
	for(long long i = 2,r; i <= x; i = r+1) {
		r = x/(x/i);
		ans += (r-i+1) * f(x/i);
	}
	ans = 1 - ans;
	add(x,ans);
	return ans;
}

int main() {
	scanf("%lld%lld",&a,&b);
	Prime();
	printf("%lld",f(b)-f(a-1));
	return 0;
}
posted @ 2020-07-18 15:43  Mogeko  阅读(112)  评论(0编辑  收藏  举报