[luoguP3768]简单的数学题

题目

传送门

题解

反演经典题型,考虑将 \(\gcd\) 拿出来枚举,然后将柿子往下推

先定义 \(S(n)=1+2+3...+n=\frac{n(n+1)}{2}\).

\[\begin{aligned} \sum_{i=1}^n\sum_{j=1}^nij\gcd(i,j) &=\sum_{d=1}^nd^3\sum_{i=1}^{\left\lfloor{n\over d}\right\rfloor}\sum_{j=1}^{\left\lfloor{n\over d}\right\rfloor}ij[(i,j)=1] \\ &=\sum_{d=1}^nd^3\sum_{i=1}^{\left\lfloor{n\over d}\right\rfloor}\sum_{j=1}^{\left\lfloor{n\over d}\right\rfloor}ij\sum_{x|i,x|j}\mu(x) \\ &=\sum_{d=1}^nd^3\sum_{x=1}^{\left\lfloor{n\over d}\right\rfloor}\mu(x)x^2S^2\left(\left\lfloor{\left\lfloor{n\over d}\right\rfloor\over x}\right\rfloor\right) \\ \end{aligned} \]

当然在这一步你可以定义一个新函数,定义

\[G(n)=\sum_{x=1}^n\mu(x)x^2S^2\left(\left\lfloor{n\over x}\right\rfloor\right) \]

然后原式就是

\[\sum_{d=1}^nd^3G(\left\lfloor{n\over d}\right\rfloor) \]

但是这样做会超时,时间复杂度大概是线性左右......

我们考虑将柿子硬推下去,令 \(T=dx,d={T\over x}\),同时我们有 \(\left\lfloor{\left\lfloor{n\over d}\right\rfloor\over x}\right\rfloor=\left\lfloor{n\over dx}\right\rfloor=\left\lfloor{n\over T}\right\rfloor\),考虑把柿子中的 \(d\) 都换成 \(T\),有

\[\begin{aligned} Ans&=\sum_{x=1}^n\mu(x)x^2\sum_{x|T}^n\left({T\over x}\right)^3S^2(\left\lfloor{n\over T}\right\rfloor) \\ \end{aligned} \]

考虑将 \(\left({T\over x}\right)^3\) 中的 \(\left({1\over x}\right)^3\) 全部拿出来,就有

\[\begin{aligned} Ans &=\sum_{x=1}^n{\mu(x)\over x}\sum_{x|T}^nT^3S^2(\left\lfloor{n\over T}\right\rfloor) \\ &=\sum_{T=1}^nT^3S^2(\left\lfloor{n\over T}\right\rfloor)\sum_{x|T}{\mu(x)\over x} \end{aligned} \]

同时我们又有 \(\sum_{x|T}{\mu(x)\over x}={\varphi(T)\over T}\)(这一步可以去查莫比乌斯反演相关资料),那么就有

\[\begin{aligned} Ans&=\sum_{T=1}^nT^3S^2(\left\lfloor{n\over T}\right\rfloor){\varphi(T)\over T} \\ &=\sum_{T=1}^nT^2\varphi(T)S^2(\left\lfloor{n\over T}\right\rfloor) \end{aligned} \]

现在考虑怎么使用杜教筛解决 \(\sum T^2\varphi(T)\).

\(f(x)=x^2\varphi(x)\),同时令 \(h(x)=x^3,g(x)=x^2\),那么

\[\begin{aligned} f*g&=\sum_{x|n}f(x)g({n\over x}) \\ &=\sum_{x|n}x^2\varphi(x)\left({n\over x}\right)^2 \\ &=n^2\sum_{x|n}\varphi(x) \\ &=n^3=h \end{aligned} \]

即可以满足 \(h=f*g\),令 \(F(n)=\sum_{i=1}^nf(i)\),那么有

\[\begin{aligned} F(n)&=\frac{\sum_{i=1}^nh(i)-\sum_{i=2}^ng(i)F(\left\lfloor{n\over i}\right\rfloor)}{g(1)} \\ &=\frac{n^2(n+1)^2}{4}-\sum_{i=2}^ni^2F(\left\lfloor{n\over i}\right\rfloor) \end{aligned} \]

就可以进行杜教筛了.

\(Ans\) 时分块,但是分块需要求到 \(\sum T^2\varphi(T)\),就用上面的杜教筛处理前缀和作差可以求得这个东西.

代码

const int maxn=4e6;

ll n,mod,inv4,inv6;

ll S[maxn+5];
map<ll,ll>mS;
int prime[maxn>>2],pcnt;
inline void sieve(){
    S[1]=1;
    rep(i,2,maxn){
        if(!S[i])prime[++pcnt]=i,S[i]=i-1;
        for(int j=1;j<=pcnt && i*prime[j]<=maxn;++j){
            if(i%prime[j]==0){
                S[i*prime[j]]=S[i]*prime[j]%mod;
                break;
            }
            S[i*prime[j]]=S[i]*S[prime[j]]%mod;
        }
    }
    rep(i,1,maxn)S[i]=(1ll*i*i%mod*S[i]%mod+S[i-1])%mod;
}

inline ll qkpow(ll a,ll n){
    ll ret=1;a%=mod;
    for(;n>0;n>>=1,a=1ll*a*a%mod)
        if(n&1)ret=1ll*ret*a%mod;
    return ret;
}
inline ll cube(ll x){x%=mod;
    return 1ll*x*x%mod*(x+1)%mod*(x+1)%mod*inv4%mod;
}
inline ll cube(const ll l,const ll r){
    return (cube(r)-cube(l-1)+mod)%mod;
}
inline ll square(ll x){x%=mod;
    return 1ll*x*(x+1)%mod*(2*x+1)%mod*inv6%mod;
}
inline ll square(const ll l,const ll r){
    return (square(r)+mod-square(l-1))%mod;
}
inline ll sum(ll x){x%=mod;
    return (1ll*x*(x+1)/2)%mod;
}

ll getS(const ll n){
    if(n<=maxn)return S[n];
    if(mS[n])return mS[n];
    ll ret=cube(n);
    for(ll l=2,r;l<=n;l=r+1){
        r=n/(n/l);
        ll tmp1=square(l,r);
        ret=(ret+mod-tmp1*getS(n/l)%mod)%mod;
    }
    return mS[n]=ret;
}

inline ll getS(const ll l,const ll r){
    return (getS(r)+mod-getS(l-1))%mod;
}

inline void init(){
    mod=readin(1ll),n=readin(1ll);
    inv4=qkpow(4,mod-2),inv6=qkpow(6,mod-2);
    sieve();
}

signed main(){
    init();
    ll ans=0;
    for(ll l=1,r;l<=n;l=r+1){
        r=n/(n/l);
        ll tmp1=sum(n/l);tmp1=1ll*tmp1*tmp1%mod;
        // ll tmp1=cube(n/l);
        ll tmp2=getS(l,r);
        ans=(ans+1ll*tmp1*tmp2%mod)%mod;
    }
    writc(ans,'\n');
    return 0;
}

用到の一些 \(\tt trick\)

首先需要熟悉这个等式

\[{\varphi(n)\over n}=\sum_{x|n}{\mu(x)\over x} \]

其次,在进行杜教筛推导的时候,用到

\[n=\sum_{x|n}\varphi(x) \]

然后就是进行莫反的时候,用得比较经典的枚举公因数,内部出现需保证 \((i,j)=1\) 的布尔式,之后用

\[\sum_{d|n}\mu(d)= \begin{cases} 1,n=1 \\ 0,n>1 \end{cases} \]

进行替换.

以及后面出现乘积 \(dx\) 时,考虑用 \(T\)\(dx\) 进行替换,然后内外层循环反复外提化简.

posted @ 2021-02-01 11:01  Arextre  阅读(84)  评论(0编辑  收藏  举报