1040 最大公約數之和——51nod

陣法閃爍——召喚題目

【思路】:本來是TLE的,但看了討論區,發現要用到歐拉函數(在數論中用於求解 [ 1 , n ] 中與 n  互質數個數 的函數),但歐拉開頭的東東就有挺多的,這裏用到的是單個數的那種歐拉函數的板子,這裏給你一個通式:

 

求單個數的歐拉函數的板子:

//本題數據較大,所以板子用long long
typedef long long ll;

ll Eular(ll m)
{
	ll i;
	ll res=m;
	for(i=2;i*i<=m;i++)
	{
		if(m%i==0)
		{
			res-=res/i;
			while(m%i==0)
				m/=i;
		}
	}
	if(m>1)
		res-=res/m;
	return res;
}

給出一個n,求1-n這n個數,同n的最大公約數的和。比如:n = 6

1,2,3,4,5,6 同6的最大公約數分別爲1,2,3,2,1,6,加在一起 = 15

 收起

輸入

1個數N(N <= 10^9)

輸出

公約數之和

輸入樣例

6

輸出樣例

15

ac代碼:

#include<cstdio>
#include<string>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<set>
#include<cmath>
using namespace std;
typedef long long ll;
const ll maxn=1e6+7;

ll Eular(ll m)
{
	ll i;
	ll res=m;
	for(i=2;i*i<=m;i++)
	{
		if(m%i==0)
		{
			res-=res/i;
			while(m%i==0)
				m/=i;
		}
	}
	if(m>1)
		res-=res/m;
	return res;
}

int main()
{
	ll i,n;
	cin>>n;
	ll ans=0;
	for(i=1;i*i<=n;i++)
	{
		if(n%i==0){
			ans+=Eular(n/i)*i;
			if(n!=i*i)
				ans+=Eular(i)*(n/i);
		}
	}
	cout<<ans<<endl;
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章