[欧拉函数]BZOJ 2226 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
1
2
5
Sample Output
1
4
55
4
55
HINT
Constraints
1 <= T <= 300000
1 <= n <= 1000000
分析
原式:$\sum _{i=1}^n lcm(i,n)$
$n\sum _{i=1}^n \frac{i}{gcd(i,n)}$
考虑直接枚举因子:
$n\sum _{d|n} \sum _{i=1}^{\frac{n}{d}} [gcd(\frac{n}{d},i)=1]i$
$n\sum _{d|n} \frac{d\varphi (d)}{2}$
线性筛预处理phi即可
#include <iostream> #include <cstdio> using namespace std; typedef long long ll; const int N=1e6+1; int T,n; bool nonprime[N]; int prime[N],cnt,phi[N]; ll ans[N]; void Solve() { phi[1]=1; for (int i=1;i<N;i++) ans[i]=1; for (int i=2;i<N;i++) { if (!nonprime[i]) prime[++cnt]=i,phi[i]=i-1; for (int j=i;j<N;j+=i) ans[j]+=1ll*i*phi[i]>>1; for (int j=1;j<=cnt;j++) { if (1ll*i*prime[j]>=N) break; nonprime[i*prime[j]]=1; if (i%prime[j]==0) { phi[i*prime[j]]=phi[i]*prime[j]; break; } phi[i*prime[j]]=phi[i]*phi[prime[j]]; } } } int main() { Solve(); for (scanf("%d",&T);T;T--) { scanf("%d",&n); printf("%lld\n",ans[n]*n); } }
在日渐沉没的世界里,我发现了你。