BZOJ 2705 Longge的问题(欧拉函数)

来源:互联网 发布:sql server select if 编辑:程序博客网 时间:2024/06/05 08:10

2705: [SDOI2012]Longge的问题

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 1966  Solved: 1230
[Submit][Status][Discuss]

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。

 

题解:这道题目求的是∑gcd(i,n)  (1<=i<=n)。   枚举n的约数k,令s(k)为满足gcd(i,n)=k的个数,所以ans=∑(k*s(k))。

因为gcd(i,n)=k,所以gcd(i/k,n/k)=1,于是s(k)=euler(n/k)。


代码如下:


#include<cstdio>#include<cstring>#include<cmath>#define LL long long LL m;LL euler(LL k){LL res=k,i;for(i=2;i*i<=k;++i){if(k%i==0)res=res/i*(i-1);while(k%i==0)k/=i;}if(k>1)res=res/k*(k-1);return res;}int main(){LL ans,n,i;while(scanf("%lld",&n)!=EOF){m=sqrt(n);ans=0;for(i=1;i<=m;++i){if(n%i==0){ans+=(LL)i*euler(n/i);if(i*i<n)ans+=(LL)(n/i)*euler(i);}}printf("%lld\n",ans);}} 


0 0