题意:求一个很大数的欧拉函数。
根据通式
目标得到n的所有质因数。
分解即可。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define in read()
#define int long long
int in{
int cnt=0,f=1;char ch=0;
while(!isdigit(ch)){
ch=getchar();if(ch=='-')f=-1;
}
while(isdigit(ch)){
cnt=cnt*10+ch-48;
ch=getchar();
}return cnt*f;
}
const int N=2000003;
int prime[N>>1],vis[N],cnt;
int ans[77],anscnt;
int mul(int a,int b,int c){
return (a*b-(int)((long double)a/c*b)*c+c)%c;
}
int ksm(int a,int b,int c){
int sum=1;
while(b){
if(b&1)sum=mul(sum,a,c);a=mul(a,a,c);b>>=1;
}return sum;
}
void prepare(){
vis[1]=1;
for(int i=2;i<=N;i++){
if(!vis[i]){prime[++cnt]=i;}
for(int j=1;j<=cnt&&prime[j]*i<=N;j++){
vis[prime[j]*i]=1;
if(i%prime[j]==0)break;
}
}
}
bool isprime(int n){
if(n<=N-3)return !vis[n];
if(!(n&1)||(n/3*3==n)||(n/5*5==n)||(n/7*7==n)||(n/61*61==n)||(n/24251*24251==n))return false;
int x=n,d=0;
while(!(x&1))x>>=1,++d;
for(int i=1;i<=7;i++){
int gu=prime[rand()%cnt+1];
gu=ksm(gu,x,n);if(n/gu*gu==n)return false;
int pre=gu;
for(int j=1;j<=d;j++){
gu=mul(gu,gu,n);
if(gu==1&&pre!=1&&pre!=n-1)return false;;
}
if(gu!=1)return false;
}return true;
}
int gcd(int a,int b){
if(!a||!b)return a^b;
return gcd(b,a%b);
}
int pollard(int n){
if(!(n&1))return 2;
if(n/3*3==n)return 3;
if(n/5*5==n)return 5;
if(n/7*7==n)return 7;
if(n/61*61==n)return 61;
if(n/24251*24251==n)return 24251;
int x=0,y=0,d=1,q=1,c=rand()%(n-1)+1;
for(int k=1;;k<<=1,q=1,y=x){
for(int i=1;i<=k;i++){
x=(mul(x,x,n)+c)%n;
q=mul(q,abs(x-y),n);
}d=gcd(q,n);if(d>1)return d;
}
}
void Break(int n){
if(n==1)return ;
if(isprime(n))return (void)(ans[++anscnt]=n);
//cout<<"# "<<n<<endl;
int x=n;
while(x==n){
x=pollard(x);
}
Break(x);
while(n/x*x==n)n/=x;
Break(n);
}
signed main(){
prepare();
while(1){
anscnt=0;
int n=in;if(!n)break;
Break(n);
sort(ans+1,ans+anscnt+1);
int len=unique(ans+1,ans+anscnt+1)-ans-1;
//for(int i=1;i<=len;i++)cout<<ans[i]<<" ";cout<<endl;
double Ans=n;
for(int i=1;i<=len;i++)Ans*=(1.0-(1.0/(double)ans[i]));
printf("%lld\n",(int)Ans);
}
return 0;
}