欧拉函数(phi)
题目描述:
已知(N),求phi(N).
输入说明:
正整数N。
输出说明:
输出phi(N)。
样例输入:
8
样例输出:
4
数据范围:
对于20%的数据,N<=10^5
对于60%的数据,N<=10^9
对于100%的数据,N<=10^18
在这里先普及一下欧拉函数:
在数论,对正整数n,欧拉函数varphi(n)是少于或等于n的数中与n互质的数的数目。此函数以其首名研究者欧拉命名,它又称为Euler's totient function、φ函数、欧拉商数等。
例如varphi(8)=4,因为1,3,5,7均和8互质。
从欧拉函数引伸出来在环论方面的事实和拉格朗日定理构成了欧拉定理的证明。
#include<iostream>
#include<cstdio>
#define ll long long
#define N 1000010LL
using namespace std;
ll prime[N],c[N],P[N],f[N],num,n;
ll poww(ll a,ll b)
{
ll base=a,r=;
while(b)
{
if(b&)r*=base;
base*=base;
b/=;
}
return r;
}
int main()
{
cin>>n;
for(ll i=;i<=min(n,N-);i++)
{
if(!f[i])
{
prime[++num]=i;P[i]=num;
for(ll j=;i*j<=min(n,N-);j++)
f[i*j]=;
}
}
ll x=n;
for(ll i=;i<=num;i++)
{
ll p=prime[i];
while(x%p==)c[i]++,x/=p;
if(x<N)if(!f[x])
{
c[P[x]]++;break;
}
if(x==)break;
}
ll ans=;
for(ll i=;i<=num;i++)
if(c[i])ans*=(prime[i]-)*poww(prime[i],c[i]-);
if(x>N)ans*=(x-);
cout<<ans;
return ;
}