【bzoj2226】[Spoj 5971] LCMSum 欧拉函数

题目描述

Given n, calculate the sum LCM(1,n) + LCM(2,n) + .. + LCM(n,n), where LCM(i,n) denotes the Least Common Multiple of the integers i and n.

输入

The first line contains T the number of test cases. Each of the next T lines contain an integer n.

输出

Output T lines, one for each test case, containing the required sum.

样例输入

3
1
2
5

样例输出

1
4
55


题解

欧拉函数

其中需要解释一下最后一个式子的推导过程:

有一个结论:当n>2时,小于n且与n互质的数的和等于$\frac{n·\varphi(n)}2$,因为若k与n互质,则n-k一定也与n互质。

当n=2时这个关系式在数值上成立,当n=1时不成立,需要特殊处理。

所以可以先筛欧拉函数,然后枚举d,将1~n所有能够整除d的数的答案加上$\frac{d·\varphi(d)}2$。最后输出答案时再加一点处理即可。

时间复杂度为调和级数的$O(n\ln n)$

#include <cstdio>
#include <algorithm>
#define N 1000010
using namespace std;
typedef long long ll;
const int m = 1000000;
int phi[N] , prime[N] , tot;
ll f[N];
bool np[N];
int main()
{
	int i , j , T , n;
	for(i = 2 ; i <= m ; i ++ )
	{
		if(!np[i]) phi[i] = i - 1 , prime[++tot] = i;
		for(j = 1 ; j <= tot && i * prime[j] <= m ; j ++ )
		{
			np[i * prime[j]] = 1;
			if(i % prime[j] == 0)
			{
				phi[i * prime[j]] = phi[i] * prime[j];
				break;
			}
			else phi[i * prime[j]] = phi[i] * (prime[j] - 1);
		}
	}
	for(i = 2 ; i <= m ; i ++ )
		for(j = i ; j <= m ; j += i)
			f[j] += (ll)i * phi[i] / 2;
	scanf("%d" , &T);
	while(T -- ) scanf("%d" , &n) , printf("%lld\n" , (f[n] + 1) * n);
	return 0;
}

 

posted @ 2017-06-15 09:44  GXZlegend  阅读(614)  评论(0编辑  收藏  举报