BZOJ2226: [Spoj 5971] LCMSum
Description
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.
Input
The first line contains T the number of test cases. Each of the next T lines contain an integer n.
Output
Output T lines, one for each test case, containing the required sum.
Sample Input
3
1
2
5
Sample Output
1
4
55
HINT
Constraints
1 <= T <= 300000
1 <= n <= 1000000
Solution
简单反演...直接套路推下去就好了。
\[\begin{aligned}
&\sum{\frac{in}{(i,j)}}\\
&=n\sum_{d|n}\sum_{i=1}^n\frac{i}{d}[(i,n)=d]\\
&=n\sum_{d|n}\sum_{i=1}^{\frac{n}{d}}[(i,\frac{n}{d})=1]i\\
&=n\sum_{d|n}\phi(\frac{n}{d})\frac{n}{2d}\\
\end{aligned}
\]
枚举一下约数就可以\(O(T\sqrt{n})\)解决本题了。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1000010;
ll phi[N];
int p[N], cnt, vis[N];
void init(int n) {
phi[1] = 1;
for(int i = 2; i <= n; ++i) {
if(!vis[i]) p[++cnt] = i, phi[i] = i - 1;
for(int j = 1; j <= cnt && i * p[j] <= n; ++j) {
vis[i * p[j]] = 1;
if(i % p[j] == 0) {
phi[i * p[j]] = phi[i] * p[j];
break;
}
phi[i * p[j]] = phi[i] * phi[p[j]];
}
}
}
ll S(ll n) {
return phi[n] * n / 2ll + (n == 1);
}
int main() {
init(N-1);
int T; scanf("%d", &T);
while(T--) {
int n; scanf("%d", &n); ll ans = 0;
for(int i = 1; i * i <= n; ++i) {
if(n % i == 0) {
ans += S(n / i);
if(n / i != i) ans += S(n / (n / i));
}
}
printf("%lld\n", 1ll * ans * n);
}
}