Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题。现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N)。
标签:
欧拉函数。求∑gcd(i, N)(1<=i <=N)。∑gcd(i,N)=∑x*sum(x),x|N。若gcd(a,N)=x,则gcd(a/x,N/x)=1,则sum(x)=phi(N/x);
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) #define ll long long int a[10000000]; void getdivisor(ll x){ int i; for(i=1;i*i<x;i++) if(x%i==0) a[++a[0]]=i,a[++a[0]]=x/i; if(i*i==x) a[++a[0]]=i; } ll getphi(int x){ ll ans=x; for(ll i=2;i*i<=x;i++) if(x%i==0){ ans=ans/i*(i-1); while(x%i==0) x/=i; } if(x!=1) ans=ans/x*(x-1);//if prime; return ans; } int main(){ ll n;scanf("%lld",&n); getdivisor(n); ll cnt=a[0],ans=0; rep(i,1,cnt) ans+=getphi(n/a[i])*a[i]; printf("%lld\n",ans); return 0; }
【数据范围】
对于60%的数据,0<N<=2^16。
对于100%的数据,0<N<=2^32。
标签:
原文地址:http://www.cnblogs.com/fighting-to-the-end/p/5722665.html