莫比乌斯反演总结

知识及相关题题解链接:https://www.cnblogs.com/peng-ym/p/8647856.html
代码收藏:

BZOJ3994 [SDOI2015]约数个数和

#include
#include
#include
#define rg register
#define il inline
#define maxn 500005
#define ll long long
using namespace std;
il int read(){rg int x = 0 , w = 1 ; rg char ch = getchar();while (ch < '0' || ch > '9'){if (ch == '-') w = -1; ch = getchar();}while (ch >= '0' && ch <= '9'){x = (x << 3) + (x << 1) + ch - '0' ; ch = getchar();}return x * w;}
int primes[maxn] , mu[10000005] , cnt , k;
bool vis[10000005];
ll sum[maxn] , g[maxn];
void prime(int n){
	vis[1] = mu[1] = 1;
	for (rg int i = 2 ; i <= n ; ++i){
		if (!vis[i])
			primes[++cnt] = i , mu[i] = -1;
		for (rg int j = 1 ; j <= cnt && i * primes[j] <= n ; ++j){
			vis[i * primes[j]] = 1;
			if (!(i % primes[j])) break;
			mu[i * primes[j]] = -mu[i];	
		}
	}
	for (rg int i = 1 ; i <= n ; ++i)
		sum[i] = sum[i - 1] + mu[i];
	for (rg int i = 1 ; i <= n ; ++i){
		for (rg int l = 1 , r ; l <= i ; l = r + 1){
			r = i / (i / l);
			g[i] += (ll)(r - l + 1) * (ll)(i / l);
		}
	}
}
int main(){
	rg int t = read();
	prime(100005);
	while (t--){
		rg int a = read() , b = read();
		rg int maxrep = min(a , b);
		ll ans = 0;
		for (rg int l = 1 , r ; l <= maxrep ; l = r + 1){
			r = min(a / (a / l) , b / (b / l));
			ans += (sum[r] - sum[l - 1]) * g[a / l] * g[b / l];
		}
		printf("%lld\n" , ans);
	}
	return 0;	
}

BZOJ2301 [HAOI2011]Problem b

#include
#include
#include
#define rg register
#define il inline
#define maxn 500005
#define ll long long
using namespace std;
il int read(){rg int x = 0 , w = 1 ; rg char ch = getchar();while (ch < '0' || ch > '9'){if (ch == '-') w = -1; ch = getchar();}while (ch >= '0' && ch <= '9'){x = (x << 3) + (x << 1) + ch - '0' ; ch = getchar();}return x * w;}
int primes[maxn] , mu[10000005] , cnt , k;
bool vis[10000005];
ll sum[maxn];
void prime(int n){
	vis[1] = mu[1] = 1;
	for (rg int i = 2 ; i <= n ; ++i){
		if (!vis[i])
			primes[++cnt] = i , mu[i] = -1;
		for (rg int j = 1 ; j <= cnt && i * primes[j] <= n ; ++j){
			vis[i * primes[j]] = 1;
			if (!(i % primes[j])) break;
			mu[i * primes[j]] = -mu[i];	
		}
	}
	for (rg int i = 1 ; i <= n ; ++i)
		sum[i] = sum[i - 1] + mu[i];
}
ll f(int a , int b){
	rg int maxrep = min(a / k , b / k);
	ll ans = 0;
	for (rg int l = 1 , r ; l <= maxrep ; l = r + 1){
		r = min(a / (a / l) , b / (b / l));
		ans += (ll)(sum[r] - sum[l - 1]) * (ll)(a / (l * k)) * (ll)(b / (l * k)); 
	}
	return ans;
}
int main(){
	rg int t = read();
	prime(100005);
	while (t--){
		rg int a = read() , b = read() , c = read() , d = read();
		k = read();
		ll ans = f(b,  d) - f(a - 1, d) - f(b , c - 1) + f(a - 1, c - 1);
		printf("%lld\n" , ans);	
	}
	return 0;	
}

BZOJ1101 [POI2007]Zap

#include
#include
#include
#define rg register
#define il inline
#define maxn 500005
#define ll long long
using namespace std;
il int read(){rg int x = 0 , w = 1 ; rg char ch = getchar();while (ch < '0' || ch > '9'){if (ch == '-') w = -1; ch = getchar();}while (ch >= '0' && ch <= '9'){x = (x << 3) + (x << 1) + ch - '0' ; ch = getchar();}return x * w;}
int primes[maxn] , mu[10000005] , cnt;
bool vis[10000005];
ll sum[maxn];
void prime(int n){
	vis[1] = mu[1] = 1;
	for (rg int i = 2 ; i <= n ; ++i){
		if (!vis[i])
			primes[++cnt] = i , mu[i] = -1;
		for (rg int j = 1 ; j <= cnt && i * primes[j] <= n ; ++j){
			vis[i * primes[j]] = 1;
			if (!(i % primes[j]))
				break;
			else
				mu[i * primes[j]] = mu[i] * -1;	
		}
	}
	for (rg int i = 1 ; i <= n ; ++i)
		sum[i] = sum[i - 1] + mu[i];
}
int main(){
	rg int t = read();
	prime(100002);
	while(t--){
		rg int a = read() , b = read() , d = read();
		rg int maxrep = min(a / d , b / d);
		ll ans = 0;
		for (rg int l = 1 , r ; l <= maxrep ; l = r + 1){
			r = min(a / (a / l) , b / (b / l) );
			ans += (ll)(a / (l * d)) * (ll)(b / (l * d)) * (ll)(sum[r] - sum[l - 1]);
		}
		printf("%lld\n" , ans);
	}
	return 0;	
}	

你可能感兴趣的:(反演)