【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; }