【bzoj2705】[SDOI2012]Longge的问题

2705: [SDOI2012]Longge的问题

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 2507  Solved: 1531
[Submit][Status][Discuss]

Description

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

Input

一个整数,为N。

Output

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

Sample Input

6

Sample Output

15
 
 
 
 
【题解】
 
设gcd(m,n)=k的m的个数为s(k),k为n的约数
 
则ans=sigma(k*s(k))
 
由gcd(m,n)=k,gcd(m/k,n/k)=1,所以s(k)=phi(n/k)
 
时间复杂度O(nlogn)
 
 1 /*************
 2   bzoj 2705
 3   by chty
 4   2016.11.4
 5 *************/
 6 #include<iostream>
 7 #include<cstdio>
 8 #include<cstring>
 9 #include<cstdlib>
10 #include<ctime>
11 #include<cmath>
12 #include<algorithm>
13 using namespace std;
14 typedef long long ll;
15 ll n,m,ans;
16 inline ll read()
17 {
18     ll x=0,f=1;  char ch=getchar();
19     while(!isdigit(ch))  {if(ch=='-')  f=-1;  ch=getchar();}
20     while(isdigit(ch))  {x=x*10+ch-'0';  ch=getchar();}
21     return x*f;
22 }
23 ll phi(ll x)
24 {
25     ll sum=x;
26     for(ll i=2;i<=m;i++)
27     {
28         if(x%i==0)  sum=sum/i*(i-1);
29         while(x%i==0)  x/=i;
30     }
31     if(x>1)  sum=sum/x*(x-1);
32     return sum;
33 }
34 int main()
35 {
36     freopen("cin.in","r",stdin);
37     freopen("cout.out","w",stdout);
38     n=read();
39     m=(ll)sqrt(n*1.0);
40     for(ll i=1;i<=m;i++)
41         if(n%i==0)  
42         {
43             ans+=i*phi(n/i);
44             if(i*i<n)  ans+=(n/i)*phi(i);
45         }
46     printf("%lld\n",ans);
47     return 0;
48 }

 

 
 
 
posted @ 2016-11-04 08:47  chty  阅读(146)  评论(0编辑  收藏  举报