/* 返回顶部 */

SP5971 LCMSUM - LCM Sum

gate

\(\sum\limits_{i=1}^{n}lcm(i,n)\)

\(=\sum\limits_{i=1}^{n}\dfrac{i\times n}{gcd(i,n)}\)

\(=n\times\sum\limits_{d|n}\sum\limits_{i=1}^{n}\dfrac{i}{d}\ [gcd(i,n)=d]\)

同除以\(d\),设\(i=\)原来的\(i/d\)

\(=n\times\sum\limits_{d|n}\sum\limits_{i=1}^{\frac{n}{d}}i\ [gcd(i,\frac{n}{d})=1]\)

因为\(gcd(n,i)=gcd(n,n-i)\),即若\(i\)\(n\)互质,则\(n-i\)也与\(n\)互质。
所以,\((1,n)\)中,与\(n\)互质的数的总和为 \(\dfrac{\varphi(n)*n}{2}\)

\(=n\times\sum\limits_{d|n} \dfrac{\varphi(\frac{n}{d})*\frac{n}{d}}{2}\)

枚举\(d\)反过来相当于枚举\(\dfrac{n}{d}\)

\(=n\times\sum\limits_{d|n} \dfrac{\varphi(d)*d}{2}\)

预处理出\(\varphi(i)\),利用类似埃氏筛的筛法,用每个数更新它的倍数。复杂度\(O(nlogn)\)

code

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define MogeKo qwq
using namespace std;

const int maxn = 1e6+10;
const int N = 1e6;

int t,prime[maxn],phi[maxn],cnt;
long long n,sum[maxn];
bool vis[maxn];

void Phi() {
	phi[1] = 1;
	for(int i = 2; i <= N; i++) {
		if(!vis[i]) {
			prime[++cnt] = i;
			phi[i] = i-1;
		}
		for(int j = 1; j <= cnt && i*prime[j] <= N; j++) {
			vis[i*prime[j]] = true;
			if(i % prime[j])
				phi[i*prime[j]] = phi[i] * (prime[j]-1);
			else {
				phi[i*prime[j]] = phi[i] * prime[j];
				break;
			}
		}
	}
}

void solve() {
	for(long long i = 1; i <= N; i++)
		for(long long j = 1; i*j <= N; j++) {
			if(i == 1) sum[i*j] += 1;
			else sum[i*j] += phi[i]*i/2;
		}
}

int main() {
	scanf("%d",&t);
	Phi();
	solve();
	while(t--) {
		scanf("%lld",&n);
		printf("%lld\n",sum[n]*n);
	}
	return 0;
}
posted @ 2020-07-19 16:37  Mogeko  阅读(84)  评论(0编辑  收藏  举报