資源限制
時間限制:1.0s 內存限制:256.0MB
問題描述
老師出了一道難題,小醬不會做,請你編個程序幫幫他,獎金一瓶醬油:
從1—n中有多少個數與n互質?
|||||╭══╮ ┌═════┐
╭╯讓路║═║醬油專用車║
╰⊙═⊙╯ └══⊙═⊙═(坑爹的題面格式化,害得我用‘|’來代替空格,複製到記事本上看就變成正版的了)
輸入格式
輸入共一行,表示一個整數n。
輸出格式
輸出共一行,表示從1—n中與n互質的數的個數。
樣例輸入
30
樣例輸出
8
數據規模和約定
60%的數據≤10^6
100%的數據≤2*10^9
解題思路:
這道題目最關鍵的一點是使用歐拉函數!!!
如果你不用歐拉函數,而是通過for循環,從1到n分別判斷是否互爲質數(用輾轉相除法可以解決),那麼恭喜你,成功超時了!所以必須使用歐拉函數。
歐拉函數的思路很簡單,就是枚舉每一個數,如果是因子,則篩去所有該因子,並且減去有該因子的所有數。代碼如下(包括了我失敗的思路在內,不過註釋掉了):
#include<bits/stdc++.h>
using namespace std;
long long lcm(int m, int n){//輾轉相除法
if(m % n == 0){
return n;
}else{
return lcm(n, m % n);
}
}
int phi(int x){//注:ans即爲phi(x)的值
int ans = x;//先令phi(x)=x,公式中的前部分
for (int i = 2; i * i <= x; i ++){//枚舉每個數(注意,phi要求的因子是質數,而這裏枚舉的是所有數。至於爲什麼要這麼枚舉,請看代碼下邊的解釋)
if(x % i == 0){//如果這個數是因子
ans -= ans / i;//套公式x*(1-1/pi)=x-x/pi即這裏的ans-=ans/i;
while(x % i == 0) x /= i;//篩去phi(x)中x的所有i因子
}
}
if(x > 1)//篩後有剩餘的數,說明這個數也是一個質因子
ans -= ans/x;//同理套公式
return ans;//答案
}
int main(){
long long n;
int count = 0;
cin >> n;
// for(int i = 1; i < n; i ++){
// if(lcm(n, i) == 1){
// count ++;
// }
// }
count = phi(n);
cout << count;
return 0;
}
感謝這位老哥的思路:https://blog.csdn.net/DT2131/article/details/52116264