mu*log 前缀和
另解(通法):对于完全加性函数 \(f(xy)=f(x)+f(y)\),可以构造 \(g(p)=x\log p +1\),然后这个多项式对 \(x^2\) 取模。
此时 \(g\) 完全积性,并且求和求 \([x^1]\) 就是原来的结果了。
\[S(n)=\sum\limits_{n=1}^N \mu(n)\log n
\]
\(\mu * \Lambda = -\mu \cdot \log\)
\[\begin{aligned}
-S(n)&=\sum\limits_{n=1}^N (\mu*\Lambda)(n)=\sum\limits_{ij\le N}\mu(i)\Lambda(j)
\\
&=\sum_{i=1}^{\sqrt{N}} \mu(i) \Psi(\lfloor N/i \rfloor) + \sum_{j=1}^{\sqrt{N}} \Lambda(j) M(\lfloor N/j \rfloor) - M(\sqrt{N})\Psi(\sqrt{N})
\\
\\
M(N)=&\sum\limits_{n\le N} \mu(n)\quad\quad\Psi(N)=\sum\limits_{n\le N} \Lambda(n)
\end{aligned}
\]
-
计算 \(M\):利用恒等式 \(\sum\limits_{d=1}^n M(\lfloor n/d \rfloor) = 1\Rightarrow M(n) = 1 - \sum\limits_{d=2}^n M(\lfloor n/d \rfloor)\)
-
计算 \(\Psi\):利用恒等式 \(\sum\limits_{d=1}^n \Psi(\lfloor n/d \rfloor) = \log (n!)\Rightarrow \Psi(n) = \log (n!) - \sum\limits_{d=2}^n \Psi(\lfloor n/d \rfloor)\)
这样就是杜教筛状物了,做到 \(\mathcal{O}(n^{2/3})\)。
斯特林公式 \(\log(n!)\sim n\log(n)-n+\frac{1}{2}\log(2\pi n)\) 这个精度就够了。
在 \(n\) 较小时候预处理 \(\log(n!)\) 即可。
这种写法精度极其有保障。
#include<bits/stdc++.h>
#define LL long long
#define D long double
#define fr(x) freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);
using namespace std;
const int N=1e7+5,M=2e5+5;const D pi=acosl(-1),I=1;
LL n,a[M];int m,B,tot,f[M];
D O[N],S[N],jc[M],g[M],ans;
inline int TO(LL x){return x<=m?x:tot-(LL)((double)(n)/x)+1;}
inline D fac(LL n){
if(n<=M-5) return jc[n];
return n*logl(n)-n+.5*logl(2*pi*n);
}
int c,pr[N/8],v[N],mu[N],s[N];
inline void init(int n)
{
for(int i=1;i<=M-5;i++) jc[i]=jc[i-1]+logl(i);
for(int i=2;i<=n;i++)
{
if(!v[i]) pr[++c]=i,mu[i]=-1;
for(int j=1,p=2;j<=c&&i*p<=n;p=pr[++j])
{
v[i*p]=1;if(i%p==0) break;
mu[i*p]=-mu[i];
}
}mu[1]=1;D _=logl(2);
for(int i=1,p=2;i<=c;_=logl(p=pr[++i])) for(LL s=p;s<=n;s*=p) O[s]=_;
for(int i=1;i<=n;i++) s[i]=s[i-1]+mu[i],S[i]=S[i-1]+O[i];
}
int main()
{
cin>>n;m=__builtin_sqrt(n);init(B=2*powl(n,2./3));
for(LL i=1,j;i<=n;i=j+1) a[++tot]=j=n/(n/i);
for(int i=1;i<=tot;i++)
{
LL t=a[i];
if(t<=B) f[i]=s[t],g[i]=S[t];
else
{
f[i]=1,g[i]=fac(t);
for(LL p=2,q,w;p<=t;p=q+1)
q=t/(t/p),w=TO(t/p),f[i]-=(q-p+1)*f[w],g[i]-=(q-p+1)*g[w];
}
}
ans=-f[m]*g[m];
for(int i=1,w;i<=m;i++) w=TO(n/i),ans+=mu[i]*g[w]+O[i]*f[w];
printf("%.5Lf",-ans);
return 0;
}

浙公网安备 33010602011771号