bzoj 2705: [SDOI2012]Longge的問題


2705: [SDOI2012]Longge的問題

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 1978  Solved: 1237
[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。

 題解:因為1到n中的數與n的最大公約數只可能是n的因子,所以我們找到所有與n有相同因子k的數的個數然后sum+=k*s[k](s[k]是指與n有相同最大公約數k的數的個數)因為gcd(m,n)=k,所以gcd(m/k,n/k)=1,這樣所有與n/k最大公約數為1的數就是與n最大公約數為k的數則s[k]=euler(n/k),同時s[n/k]=euler(k);

#include<stdio.h>
#include<string.h>
#include<cstdio> 
#include<string>
#include<math.h>
#include<algorithm>
#define LL long long
#define PI atan(1.0)*4
#define DD double
#define MAX 2002000
#define mod 100
#define dian 1.000000011
#define INF 0x3f3f3f
using namespace std;
int el(int x)
{
	int ans=x;
	int i,j;
	for(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);
	return ans;
}
LL s[MAX]; 
int main()
{
    LL n,m,j,i,t,k;
    while(scanf("%lld",&n)!=EOF)
    {
        LL sum=0;
        k=0;
    	for(i=1;i<=sqrt(n);i++)
    	{
    		if(n%i==0)
    		{
    			sum+=el(n/i)*i;
    			if(i*i<n)
    			    sum+=(n/i)*el(i);
    			//因為i只能取到n的平方根出,所以平方根后n的因子取不到
				//這句是求平方根后與n的公約數 
    		}
    	}
    	printf("%lld\n",sum);
    }
	return 0;
}

  


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com