51nod 1575 Gcd and Lcm

Link
\(f(i)=\sum\limits_{j=1}^i\sum\limits_{k=1}^i\operatorname{lcm}(\gcd(i,j),\gcd(i,k))\),那么\(ans=\sum\limits_{i=1}^nf(i)\)
根据直觉\(f(n)\)肯定是积性函数。

\[\begin{aligned} f(n)&=\sum\limits_{i=1}^n\sum\limits_{j=1}^n\operatorname{lcm}(\gcd(n,i),\gcd(n,j))\\ &=\sum\limits_{d|n}\sum\limits_{g|n}\operatorname{lcm}(d,g)\sum\limits_{i=1}^n[\gcd(n,i)=d]\sum\limits_{j=1}^n[\gcd(n,j)=g]\\ &=\sum\limits_{d|n}\sum\limits_{g|n}\operatorname{lcm}(d,g)\varphi(\frac nd)\varphi(\frac ng) \end{aligned} \]

先考虑怎么拆\(\operatorname{lcm}\)

\[\begin{aligned} \operatorname{lcm}(n,m)&=\frac{nm}{\gcd(n,m)}\\ &=\sum\limits_{d|\gcd(n,m)}\frac nd\frac mdd[\gcd(\frac nd,\frac md)=1]\\ &=\sum\limits_{d|\gcd(n,m)}\sum\limits_{g|\gcd(\frac nd,\frac md)}\mu(g)g^2\frac n{dg}\frac m{dg}d \end{aligned} \]

然后把这个代进去。

\[\begin{aligned} f(n)&=\sum\limits_{d|n}\sum\limits_{g|n}\operatorname{lcm}(d,g)\varphi(\frac nd)\varphi(\frac ng)\\ &=\sum\limits_{x|n}\sum\limits_{y|n}\sum\limits_{u|\gcd(x,y)}\sum\limits_{v|\gcd(\frac xu,\frac yu)}\mu(v)uv^2\frac x{uv}\frac y{uv}\varphi(\frac nx)\varphi(\frac ny)\\ &=\sum\limits_{u|n}u\sum\limits_{v|\frac nu}\mu(v)v^2(\sum\limits_{w|\frac n{uv}}w\varphi(\frac n{uvw}))^2 \end{aligned} \]

也就是说\(f=id\times(\mu\cdot id_2)\times(\varphi\times id)^2\)。(幂在点积意义下)
因此\(f\)是积性函数,但是\(\sum f\)看上去就不太能杜教筛,因此考虑zzt筛。

\[\begin{aligned} f(p^e)&=\sum\limits_{i=1}^{p^e}\sum\limits_{j=1}^{p^e}\operatorname{lcm}(\gcd(i,p^e),\gcd(j,p^e))\\ &=\sum\limits_{i=0}^e\sum\limits_{j=0}^ep^{\max(i,j)}\varphi(p^{e-i})\varphi(p^{e-j})\\ &=\sum\limits_{i=0}^ep^i\varphi(p^{e-i})(\varphi(p^{e-i})+2\sum\limits_{j=0}^{i-1}\varphi(p^{e-j}))\\ &=p^e(1+2\sum\limits_{i=0}^{e-1}p^{e-i}-p^{e-i-1})+\sum\limits_{i=0}^{e-1}(p-1)^2p^{e-1}(p^{e-i-1}+2\sum\limits_{j=0}^{i-1}p^{e-j-1})\\ &=(2e+1)(p^{2e}-p^{2e-1})+p^{e-1} \end{aligned} \]

\(f(p)=3p^2-3p+1\)

#include<cstdio>
using u32=unsigned int;
using u64=unsigned long long;
const int N=100007;
int n,cnt,tot,lim,pr[N],is[N],num[N];u32 h[N];
int read(){int x;scanf("%d",&x);return x;}
int getid(int x){return x<=lim? x:cnt+1-n/x;}
u64 S(u64 p,int deg){return !deg? p:deg==1? p*(p+1)/2:p%6==1? (p+1)*(p+p+1)/6*p:p%6==4? p*(p+p+1)/6*(p+1):p*(p+1)/6*(p+p+1);}
u32 g(int n,int m)
{
    if(n<pr[m]) return 0;
    u32 ans=h[getid(n)]-h[pr[m]];u64 p,q;
    for(int i=m+1,e;i<=tot&&pr[i]*pr[i]<=n;++i) for(p=pr[i],e=1,q=p*(p-1);p<=(u64)n;++e,p*=pr[i],q*=(u64)pr[i]*pr[i]) ans+=((e+e+1)*q+p/pr[i])*(g(n/p,i)+(e>1));
    return ans;
}
void init()
{
    static u32 t[3][N];cnt=0;
    for(lim=1;(lim+1)*(lim+1)<=n;++lim);
    for(int l=1,r;l<=n;l=r+1) r=n/(n/l),num[++cnt]=r;
    for(int i=1;i<=cnt;++i) for(int k=0;k<3;++k) t[k][i]=S(num[i],k)-1;
    for(int i=1;i<=tot&&pr[i]<=lim;++i) for(int j=cnt;j&&pr[i]*pr[i]<=num[j];--j) for(int k=0;k<3;++k) t[k][j]-=(k>=1? pr[i]:1)*(k>=2? pr[i]:1)*(t[k][getid(num[j]/pr[i])]-t[k][pr[i-1]]);
    for(int i=1;i<=cnt;++i) h[i]=3*(t[2][i]-t[1][i])+t[0][i];
}
void solve()
{
    n=read();
    init();
    printf("%u\n",g(n,0)+1);
}
int main()
{
    for(int i=2,j;i<=40000;++i) if(!is[i]) for(pr[++tot]=i,j=i*2;j<=40000;j+=i) is[j]=1;
    for(int T=read();T;--T) solve();
}
posted @ 2020-05-24 16:49  Shiina_Mashiro  阅读(165)  评论(0编辑  收藏  举报