资源限制
时间限制: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