欧拉函数

问题背景

求得小于 $N$ 且与 $N$互质的数字的个数

一些比较重要的性质

  • 对于素数 $k$ 的欧拉函数取值是 $k - 1$
  • 欧拉函数是积性函数 $\varphi(m n) = \varphi(m) \varphi(n)$

求解公式

其中 $p_1, p_2, \dots p_n$ 是 $n$ 的质因数

代码写法

单个数求值取模(参考的是质因数分解的做法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {

static int max(int... a) {
int res = a[0];
for (int i : a) res = Math.max(res, i);
return res;
}

static int min(int... a) {
int res = a[0];
for (int i : a) res = Math.min(res, i);
return res;
}

static class Read {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stringTokenizer = new StringTokenizer("");

String next() {
while (!stringTokenizer.hasMoreTokens()) {
try {
stringTokenizer = new StringTokenizer(bufferedReader.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return stringTokenizer.nextToken();
}

int nextInt() {return Integer.parseInt(next());}
long nextLong() {return Long.parseLong(next());}
}

static Read in = new Read();
static final int N = (int) (1e6 + 5);
static final int MOD = (int) (1e9 + 7);
static int n;

static int phi(int n) {
int res = n;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
res -= res / i;
while (n % i == 0) n /= i;
}
}
if (n > 1) res -= res / n;
return res;
}


public static void main(String[] args) {
n = in.nextInt();
System.out.println(phi(n));
}
}

区间内的个数(参考的是线性筛的做法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {

static int max(int... a) {
int res = a[0];
for (int i : a) res = Math.max(res, i);
return res;
}

static int min(int... a) {
int res = a[0];
for (int i : a) res = Math.min(res, i);
return res;
}

static class Read {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stringTokenizer = new StringTokenizer("");

String next() {
while (!stringTokenizer.hasMoreTokens()) {
try {
stringTokenizer = new StringTokenizer(bufferedReader.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return stringTokenizer.nextToken();
}

int nextInt() {return Integer.parseInt(next());}
long nextLong() {return Long.parseLong(next());}
}

static Read in = new Read();
static final int N = (int) (1e6 + 5);
static final int MOD = (int) (1e9 + 7);
static int n;
static int[] phi = new int[N], primes = new int[N];
static boolean[] comp = new boolean[N];

static void init() {
phi[1] = 1;
int cnt = 0;
for (int i = 2; i <= n; i++) {
if (!comp[i]) {
primes[cnt++] = i;
phi[i] = i - 1;
}
for (int j = 0; (long) i * primes[j] <= n; j++) {
comp[i * primes[j]] = true;
if (i % primes[j] == 0) {
phi[i * primes[j]] = phi[i] * primes[j];
break;
}
phi[i * primes[j]] = phi[i] * (primes[j] - 1);
}
}
}


public static void main(String[] args) {
n = in.nextInt();
init();
System.out.println(phi[n]);
}
}