[BZOJ4916]神犇和蒟蒻
题目
让你计算俩东西:
\[A=\sum_{i=1}^n\mu(i^2)\\
B=\sum_{i=1}^n\varphi(i^2)
\]
数据范围:\(n\le 10^9\).
题解
不难发现 \(A=1\).
对于 \(B\) 而言,可以感性理解,发现 \(\varphi(i^2)=i\times \varphi(i)\),即我们需要计算
\[B=\sum_{i=1}^ni\times \varphi(i)
\]
令 \(f(i)=i\times \varphi(i)\),那么有
\[\begin{aligned}
f*g=\sum_{d|n}d\cdot \varphi(d)\cdot g(\frac{n}{d})
\end{aligned}
\]
这个 \(d\) 有些不爽,我们尝试构造 \(g(\frac{n}{d})\) 将其消掉,定义 \(g(\frac{n}{d})=\frac{n}{d}\) 即 \(g=id\),那么有
\[\begin{aligned}
f*g&=\sum_{d|n}d\cdot \varphi(d)\cdot \frac{n}{d} \\
&=\sum_{d|n}n\cdot \varphi(d) \\
&=n\sum_{d|n}\varphi(d)=n^2
\end{aligned}
\]
也有 \(h(i)=i^2\),而我们有
\[\sum_{i=1}^nh(i)=\frac{n(n+1)(2n+1)}{6}
\]
带入杜教筛公式,有
\[B=\frac{n(n+1)(2n+1)}{6}-\sum_{i=2}^ng(i)\cdot f(\left\lfloor\frac{n}{i}\right\rfloor)
\]
数论分块即可.
代码
const int mod=1e9+7;
const int maxn=2e6;
const int inv6=166666668;
int phi[maxn+5];
int prime[maxn>>2],pcnt;
inline void sieve(){
phi[1]=1;
rep(i,2,maxn){
if(!phi[i])prime[++pcnt]=i,phi[i]=i-1;
for(int j=1;j<=pcnt && i*prime[j]<=maxn;++j){
if(i%prime[j]==0){
phi[i*prime[j]]=1ll*phi[i]*prime[j]%mod;
break;
}
phi[i*prime[j]]=1ll*phi[i]*phi[prime[j]]%mod;
}
}
rep(i,1,maxn)phi[i]=(1ll*i*phi[i]+phi[i-1])%mod;
}
int n;
inline int func(const int n){
return (1ll*n*(n+1)%mod*(2*n+1)%mod*inv6)%mod;
}
map<int,ll>memo;
inline int calc(const int l,const int r){
return (1ll*(r-l+1)*(l+r)/2)%mod;
}
int getS(const int n){
if(n<=maxn)return phi[n];
if(memo[n])return memo[n];
int ret=func(n);
for(int l=2,r;l<=n;l=r+1){
r=n/(n/l);
ret=(ret+mod-1ll*calc(l,r)*getS(n/l)%mod)%mod;
}
return memo[n]=ret;
}
signed main(){
// freopen("shit.out","w",stdout);
n=readin(1);
writc(1,'\n');
sieve();
writc(getS(n),'\n');
return 0;
}