BZOJ2190【莫比乌斯反演】【欧拉函数】

/* I will wait for you */

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <string>
#define make make_pair
#define fi first
#define se second

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef map<int, int> mii;

const int maxn = 100010;
const int maxm = 1010;
const int maxs = 26;
const int inf = 0x3f3f3f3f;
const int P = 1000000007;
const double error = 1e-9;

inline ll read()
{
	ll x = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9')
		  f = (ch == '-' ? -1 : 1), ch = getchar();
	while (ch >= '0' && ch <= '9')
	 	  x = x * 10 + ch - '0', ch = getchar();
	return x * f;
}

int n, mu[maxn], pri[maxn], ma[maxn];
ll ans = 2;

void init()
{
	mu[1] = 1;
	for (int i = 2; i * i <= n; i++) 
		if (pri[i] == 0) {
			for (int j = i * i; j <= n; j += i)
				pri[j] = 1, ma[j] = max(ma[j], i);
			}
	for (int i = 2; i <= n; i++) {
		if (pri[i] == 0)
			mu[i] = -1;
		else if (i /  ma[i] % ma[i] == 0)
			mu[i] = 0;
		else
			mu[i] = -mu[i / ma[i]];
	}
}
int main()
{
	n = read() - 1, init();
	
	for (int i = 1; i <= n; i++)
		ans += mu[i] * (n / i) * (n / i); 
	
	printf("%lld\n", ans);

	return 0;
}

想了想其实就是欧拉函数的前缀和.现在看到互质第一反应已经是莫比苏斯反演了.

/* I will wait for you */

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <string>
#define make make_pair
#define fi first
#define se second

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef map<int, int> mii;

const int maxn = 100010;
const int maxm = 1010;
const int maxs = 26;
const int inf = 0x3f3f3f3f;
const int P = 1000000007;
const double error = 1e-9;

inline ll read()
{
	ll x = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9')
		  f = (ch == '-' ? -1 : 1), ch = getchar();
	while (ch >= '0' && ch <= '9')
	 	  x = x * 10 + ch - '0', ch = getchar();
	return x * f;
}

int n, fa[maxn], pri[maxn], ma[maxn];
ll ans = 3;

void init()
{
	for (int i = 2; i * i <= n; i++) 
		if (pri[i] == 0) {
			for (int j = i * i; j <= n; j += i)
				pri[j] = 1, ma[j] = max(ma[j], i);
			}
	for (int i = 2; i <= n; i++) {
		if (pri[i] == 0)
			fa[i] = i - 1;
		else if (i /  ma[i] % ma[i] == 0)
			fa[i] = fa[i / ma[i]] * ma[i];
		else
			fa[i] = fa[i / ma[i]] * (ma[i] - 1);
	}
}
int main()
{
	n = read() - 1, init();
	
	for (int i = 1; i <= n; i++)
		ans += 2 * fa[i];
	
	printf("%lld\n", ans);

	return 0;
}

你可能感兴趣的:(BZOJ2190【莫比乌斯反演】【欧拉函数】)