欧拉函数: 😄如果是求一个数的欧拉函数值用普通公式法(时间复杂度
):
int eul(int n){
int ans=n;
for(int i=2;i<=n/i;i++){//找质数并处理
if(n%i==0) ans=ans/i*(i-1);//ans*=(i-1)/i==0,也不能ans=ans*(i-1)/i,越界
while(n%i==0) n/=i;
}
if(n>1) ans=ans/n*(n-1);//ans*=(n-1)/n==0,也不能 ans=ans*(n-1)/n;容易越界
return ans;
} 😃如果是求1~n的欧拉函数值用线性筛法(时间复杂度为n【如果用普通公式法复杂度为 1.当i mod pj ==0时,%3Di*pj*(1-%5Cfrac%7B1%7D%7Bp1%7D)*(1-%5Cfrac%7B1%7D%7Bp2%7D)*(1-%5Cfrac%7B1%7D%7Bp3%7D)...*(1-%5Cfrac%7B1%7D%7Bpn%7D))
即: %3Dphi(i)*pj)
2.当i mod pj !=0时,%3Di*pj*(1-%5Cfrac%7B1%7D%7Bp1%7D)*(1-%5Cfrac%7B1%7D%7Bp2%7D)*(1-%5Cfrac%7B1%7D%7Bp3%7D)...*(1-%5Cfrac%7B1%7D%7Bpn%7D)*(1-%5Cfrac%7B1%7D%7Bpj%7D))
即,%3Dphi(i)*pj*(1-%5Cfrac%7B1%7D%7Bpj%7D))
用线性筛法模板随便把欧拉函数求出
void euls(){
phi[1]=1;
for(int i=2;i<=n;i++){//改
if(!st[i]){
prime[cnt++]=i;
phi[i]=i-1;//+++++
}
for(int j=0;prime[j]<=n/i;j++){
st[prime[j]*i]=true;
if(i%prime[j]==0){
phi[prime[j]*i]=phi[i]*prime[j]; //+++++
break;
}else{
phi[prime[j]*i]=phi[i]*(prime[j]-1);//+++++
}
}
}
} 下面是两道题的代码
acwing873: #include <bits/stdc++.h>
using namespace std;
int t,n;
int eul(int n){
int ans=n;
for(int i=2;i<=n/i;i++){
if(n%i==0) ans=ans/i*(i-1);//ans*=(i-1)/i==0,也不能ans=ans*(i-1)/i,越界
while(n%i==0) n/=i;
}
if(n>1) ans=ans/n*(n-1);//ans*=(n-1)/n==0,也不能 ans=ans*(n-1)/n;容易越界
return ans;
}
int main(int argc, char** argv) {
cin>>t;
while(t--){
cin>>n;
cout<<eul(n)<<endl;
}
return 0;
} acwing874:
#include <iostream>
using namespace std;
int n;
const int N=1000006;
int prime[N],phi[N],cnt;//phi记录各个数的欧拉函数值
bool st[N];
void euls(){
phi[1]=1;
for(int i=2;i<=n;i++){//改
if(!st[i]){
prime[cnt++]=i;
phi[i]=i-1;//+++++
}
for(int j=0;prime[j]<=n/i;j++){
st[prime[j]*i]=true;
if(i%prime[j]==0){//如果i mod pj ==0
phi[prime[j]*i]=phi[i]*prime[j]; //+++++
break;
}else{//i mod pj !=0
phi[prime[j]*i]=phi[i]*(prime[j]-1);//+++++
}
}
}
}
int main(int argc, char** argv) {
cin>>n;
euls();
long long ans=0;
for(int i=1;i<=n;i++){
ans+=phi[i];
}
cout<<ans<<endl;
return 0;
} 
京公网安备 11010502036488号