bzoj 2705: [SDOI2012]Longge的问题——欧拉定理

Description

Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题。现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N)。

Input

一个整数,为N。

Output

一个整数,为所求的答案。

Sample Input

6

Sample Output

15

HINT

 

【数据范围】

对于60%的数据,0<N<=2^16。

对于100%的数据,0<N<=2^32。

———————————————————————

这道题如果一个数x gcd(n,x)==y 那么gcd(b/y,x/y)==1

所以我们枚举因数d 求一下1-n/d有多少个数和n/d的gcd为1 这个可以用欧拉函数

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
const int M=1e3+7;
LL read(){
    LL ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
LL n,v,ans;
int p[M],cnt;
LL f(LL x){for(int i=1;i<=cnt;i++)if(x%p[i]==0) x=x/p[i]*(p[i]-1); return x;}
int main(){
    n=read(); v=n;
    for(LL x=2;x*x<=v;x++)if(v%x==0){
        p[++cnt]=x;
        while(v%x==0) v/=x;
    }
    if(v!=1) p[++cnt]=v;
    for(LL x=1;x*x<=n;x++)if(n%x==0){
        LL y=n/x;
        ans=ans+y*f(x);
        if(x!=y) ans=ans+x*f(y);
    }printf("%lld\n",ans);
    return 0;
}
View Code

 

posted @ 2017-10-14 07:32  友人Aqwq  阅读(163)  评论(0编辑  收藏  举报