P1891 疯狂 LCM
作者:互联网
P1891 疯狂 LCM
题意:
给定 \(n\),求:
\[\sum_{i = 1}^n \operatorname{lcm}(i, n) \]思路:
先把 \(lcm\) 换成 \(gcd\):
\[\ n\sum_{i = 1}^n \frac{i}{gcd(i,n)} \]加一个枚举因数的 \(\sum\)
\[\ n\sum_{d|n} \sum_{i = 1}^n \frac{i}{d}[gcd(i,n)=d] \]即
\[\ n\sum_{d|n} \sum_{i = 1}^n \frac{i}{d}[gcd(\frac{i}{d},\frac{n}{d})=1] \]用 \(i=\frac id\) 替换原本的 \(i\)
\[\ n\sum_{d|n} \sum_{i = 1}^{\frac nd} i[gcd(i,\frac{n}{d})=1] \]由于 \(d,\frac{n}{d}\) 成对出现,可以用 \(d\) 替换 \(\frac{n}{d}\)
\[\ n\sum_{d|n} \sum_{i = 1}^{d} i[gcd(i,\frac{n}{d})=1] \]可以发现这个式子与 \(\varphi(d)\) 有一定联系,因为
\[\varphi(d)=\sum_{i = 1}^{d} [gcd(i,\frac{n}{d})=1] \]多了一个 \(i\)
一个小定理:若 \(gcd(a,b)=1\) \((a<b)\) 则 \(gcd(b-a,b)=1\)
因此原式可以两对两对的统计,可以写成
\[\ n\sum_{d|n} \sum_{i = 1}^{d} \varphi(d)\frac d2 \]这样就可以计算了
注意 \(d=1\) 的时候特判
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-1;
ch=getchar();
}
while(isdigit(ch)){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
const int N=1e6+5;
#define ll long long
int cnt;
int p[N],phi[N];
bool not_p[N];
ll f[N];
inline void get_phi(){
phi[1]=1;
not_p[1]=1;
for(int i=2;i<N;++i){
if(!not_p[i]){
p[++cnt]=i;
phi[i]=i-1;
}
for(int j=1;j<=cnt&&i*p[j]<N;++j){
not_p[i*p[j]]=1;
if(i%p[j]==0){
phi[i*p[j]]=phi[i]*p[j];
break;
}
else
phi[i*p[j]]=phi[i]*(p[j]-1);
}
}
for(int i=1;i<N;++i)
for(int j=1;j*i<N;++j)
f[i*j]+=(i==1?1:1ll*phi[i]*i/2);
}
inline ll solve(int x){
return f[x]*x;
}
signed main(){
int T=read();
get_phi();
while(T--)
cout<<solve(read())<<endl;
}
标签:ch,frac,gcd,int,sum,P1891,疯狂,varphi,LCM 来源: https://www.cnblogs.com/into-qwq/p/16446120.html