欧拉函数O(
n
\sqrt{n}
n)
求n的欧拉函数,即1~n与n互质的数有哪些,即gcd(n,x)==1的x有多少个
传送门
注意我们要除干净质因子,这样才能把所有质因子求出
然后对于每个质因子/i*(i-1)即可
#include<iostream>
using namespace std;
int phi(int n){
int res=n;
for(int i=2;i<=n/i;i++){
if(n%i==0){
res=res/i*(i-1);
while(n%i==0)n/=i;
}
}
if(n>1)res=res/n*(n-1);
return res;
}
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
cout<<phi(n)<<endl;
}
return 0;
}
O(n)求1~n所有数的欧拉函数
用到了线性筛的思想
要记住线性筛第一层循环是n,这样才能遍历所有1~n所有数
然后如果说i%primes[j]==0,那么primes[j]就已经是i的一个质因子了,而且phi[i]包含了primes[j]的所有质因子,所以phi[i]只需要*primes[j]即可
如果i%primes[j]!=0
那么phi还需要多乘个(1-1/primes[j])
即phi[i]要 *(primes[j]-1)
#include<iostream>
using namespace std;
const int N=1e6+10;
int primes[N],phi[N];
bool st[N];
int cnt=0;
void euler(int n){
phi[1]=1;
for(int i=2;i<=n;i++){//是n个
if(!st[i]){
primes[cnt++]=i;
phi[i]=i-1;
}
for(int j=0;primes[j]<=n/i;j++){
st[primes[j]*i]=1;
if(i%primes[j]==0){
phi[primes[j]*i]=primes[j]*phi[i];
break;
}
phi[primes[j]*i]=(primes[j]-1)*phi[i];
}
}
}
int main(){
int n;
cin>>n;
long long res=0;
euler(n);
for(int i=1;i<=n;i++){
// cout<<primes[i]<<endl;
res+=phi[i];
}
cout<<res;
return 0;
}