SP5971 LCMSUM

gate

(sumlimits_{i=1}^{n}lcm(i,n))

(=sumlimits_{i=1}^{n}dfrac{i imes n}{gcd(i,n)})

(=n imessumlimits_{d|n}sumlimits_{i=1}^{n}dfrac{i}{d} [gcd(i,n)=d])

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

(=n imessumlimits_{d|n}sumlimits_{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 imessumlimits_{d|n} dfrac{varphi(frac{n}{d})*frac{n}{d}}{2})

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

(=n imessumlimits_{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
",sum[n]*n);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/mogeko/p/13340252.html