【bzoj2705】[SDOI2012]Longge的问题
2705: [SDOI2012]Longge的问题
Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 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 }