欧拉定义
百度的定义就不copy了 简单的说就是给定一个正整数n 小于n的正整数与n互质的个数 例如phi[8]=4 (1,3,5,7与8互质)
代码主要是用其公式
其中x是要求的数 n是x进行唯一分解定理后的不同pi的个数 pi是唯一分解定理后的数字(ex 20=2^2*5 那么p就有两个值 2和5) 敲重点 唯一分解定理
欧拉性质
欧拉函数是积性函数:*当a,b互质的时候(gcd(a,b)=1) , phi[a*b]=phi[a]phi[b]
欧拉函数优化算法代码
#include<iostream>
#include<algorithm>
#include<cstring>
#define maxn 1000
#define ll long long
using namespace std;
int oula_youhua(int n){
int rea=n;//rea相当于公式中的x(将其 ∏分开存储每次乘之后的值)
for(int i=2;i*i<=n;i++){
//i*i<=n优化 nlogn复杂度
if(n%i==0){
//当找到第一个素数的时候
rea=rea-rea/i;//rea乘一下更新 (就是套公式)
do{
//并且消除n中所有i的影响 并且继续寻找下一个唯一分解定理质数
n/=i;
}while(n%i==0);
}
}
if(n>1)//当结束后 特殊处理最后一个数
rea=rea-rea/n;
return rea;
}
int main(){
while(1){
int x;
cin>>x;
cout<<oula_youhua(x)<<endl;
}
return 0;
}
欧拉线性筛 O(n)
#include<iostream>
#include<algorithm>
#define maxn 1000
using namespace std;
int phi[maxn];
int prime[maxn];
int isprime[maxn<<2];
int tot=0;
void getphi(){
//就是在素数筛的操作
for(int i=2;i<maxn;i++){
if(!isprime[i]){
prime[tot++]=i;
phi[i]=i-1;//如果为素数 那么个数就是i-1个
}
for(int j=0;j<tot;j++){
//遍历目前的素数
if(i*prime[j]>maxn)break;//如果大于范围退出
isprime[i*prime[j]]=1;//标记素数
if(i%prime[j]==0){
//如果这个数和素数有约数的话 phi更新(因为有约数 有公式可得 从两个数之间提出公共因子prime 乘以phi【】更新)
phi[i*prime[j]]=phi[i]*prime[j];// 由于公式x∏(1-1/pi) 可以提出来值
break;
}
phi[i*prime[j]]=phi[i]*phi[prime[j]];//如果没有约数 那么i和prime就是相对素数由于性质gcd(a,b)==1 → phi[a*b]=phi[a]*phi[b]
}
}
}
int main(){
getphi();
phi[1]=1;
for(int i=1;i<10;i++){
cout<<phi[i]<<endl;
}
return 0;
}
蒟蒻今天终于补了集训的第一篇博客
说到底还是一条懒狗 落泪.jpg