試題 算法提高 歐拉函數
問題描述
老師出了一道難題,小醬不會做,請你編個程序幫幫他,獎金一瓶醬油:
從1—n中有多少個數與n互質?
|||||╭══╮ ┌═════┐
╭╯讓路║═║醬油專用車║
╰⊙═⊙╯ └══⊙═⊙═(坑爹的題面格式化,害得我用‘|’來代替空格,複製到記事本上看就變成正版的了)
輸入格式
輸入共一行,表示一個整數n。
輸出格式
輸出共一行,表示從1—n中與n互質的數的個數。
樣例輸入
30
樣例輸出
8
數據規模和約定
60%的數據≤10^6
100%的數據≤2*10^9
PS:
這個題先附上暴力代碼,只能過90的分,後面有大佬的歐拉函數的解法
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
sc.close();
ArrayList<Integer> list = new ArrayList<Integer>();
int temp = n;
for (int i = 2; temp != 1; i++) {
if (temp % i == 0) list.add(i);
while (temp % i == 0) {
temp /= i;
}
}
int count = 0;
// System.out.println(list);
boolean[] bool = new boolean[n];
for (int i : list) {
int index = 1;
while (index * i < n) {
bool[index * i] = true;
index++;
}
}
for (int i = 1; i < n; i++) {
if (!bool[i]) {
count++;
}
}
// A:
// for (int i = 1; i < n; i++) {
// for (int j : list){
// if(i % j == 0){
// continue A;
// }
// }
// count++;
// }
System.out.println(count);
}
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
long ans = n;
for (int i = 2; i * i <= n; i++) {//優化 O(sqrt(n)) 不過要在出口 if(n>1)ans/n*(n-1) O(n)不用
if (n % i == 0) {
ans = ans / i * (i - 1);////n*(1-(1/p))轉化爲n/p*(p-1)
while (n % i == 0)
n /= i;
}
}
if (n > 1)
System.out.println(ans / n * (n - 1));
else
System.out.println(ans);
}
}