浏览器标题切换
浏览器标题切换end
把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

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);
    }
}
posted @ 2019-03-26 22:54  henry_y  阅读(221)  评论(0编辑  收藏  举报