【题解】LOJ #6052 「雅礼集训 2017 Day11」DIV【莫比乌斯反演】

题目链接

题意

定义 \(a\mathrm i+b\)\(n\) 的约数当且仅当存在 \(c\mathrm i +d\) 使得 \((a\mathrm i +b)(c\mathrm i +d)=n(a,b,c,d\in \mathbf{N})\)

\(h(n)\)\(n\) 的约数的实部之和,要求实部大于 \(0\)。求 \(H(n)=\sum_i^n h(i)\)\(n\leq 10^{10}\)

题解

先考虑虚部大于 \(0\) 的情况。设 \(n=(a\mathrm i +b)(c\mathrm i d)(a>0)\),则 \(ac-bd=n,ad+bc=0\)。设:

\[\begin{aligned} a=px\\ p=qx\\ c=py\\ d=-qy\\ p\bot q \end{aligned} \]

\((p,q,x,y)\) 唯一确定 \((a,b,c,d)\)

记:

  • \[g(n)=\sum_{p^2+q^2=n} [p\bot q]p \]

  • \[f(n)=\sum_{p^2+q^2=n}p \]

  • \[S(n)=\sum_{i=1}^{n}\sigma_1(i) \]

问题化为:

\[\begin{aligned} &\sum_{p,q,x,y}[p\bot q][xy(p^2+q^2)\leq n]px\\ =&\sum_{i=1}^{n} \left(\sum_{p^2+q^2=i}[p\bot q]p\right)+\left(\sum_{xy\leq n /i}x\right)\\ =&\sum_{i=1}^{n}g(i)S(\lfloor \dfrac{x}{i}\rfloor) \end{aligned} \]

\(S(n)\) 在小数据处线性筛预处理,大数据处整除分块。

\[\begin{aligned} \sum_{i=1}^n g(i)=&\sum_{p^2+q^2\leq n}[p\bot q]p\\ &\sum_{i=1}^{\sqrt n}i\mu(i)\sum_{j=1}^{\lfloor \frac{n}{i^2}\rfloor}f(j) \end{aligned} \]

\(g\) 的前缀和暴力计算,\(f\) 的前缀和可以暴力枚举 \(p\)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int M1=1.2e5,M2=5e6,mod=1004535809,inv2=(mod+1)/2;

bool boo[M2];
int sig[M2],mu[M2],pri[M2],r[M2],cnt;
struct IZHR2MJy{
    int lim=0;
    void init(int n){
        sig[1]=1;
        mu[1]=1;
        lim=n;
        for(int i=2;i<=n;i++){
            if(!boo[i]){
                r[i]=1;
                sig[i]=i+1;
                pri[cnt++]=i;
                mu[i]=-1;
            }
            for(int j=0;j<cnt&&i*pri[j]<=n;j++){
                int v=i*pri[j];
                boo[v]=1;
                if(i%pri[j]){
                    sig[v]=sig[i]*1ll*sig[pri[j]]%mod;
                    mu[v]=-mu[i];
                    r[v]=i;
                }else{
                    sig[v]=(sig[i]*1ll*pri[j]+sig[r[i]])%mod;
                    r[v]=r[i];
                    break;
                }
            }
        }
        for(int i=1;i<=n;i++)sig[i]=(sig[i-1]+sig[i])%mod;
    }
    int _(ll x){
        x%=mod;
        return x*(x+1)/2%mod;
    }
    int operator()(ll x){
        if(x<=lim)return sig[x];
        int ans=0;
        for(ll l=1,r;l<=x;l=r+1){
            r=x/(x/l);
            int t=x/l%mod;
            ans=(ans+(_(r)-_(l-1)+mod)*1ll*t)%mod;
        }
        return ans;
    }
}S;

int F(ll n){
    int ans=0;
    for(ll i=1;i*i<=n;i++)
        ans=(ans+i*int(sqrt(n-i*i)))%mod;
    return ans;
}
int G(ll n){
    int lsti=-1,lstf=0,ans=0;
    for(ll i=1;i*i<=n;i++){
        if(n/i/i!=lsti){
            lsti=n/i/i;
            lstf=F(n/i/i);
        }
        ans=(ans+mu[i]*i*lstf)%mod;
    }
    return ans;
}

int main(){
    ll n;
    scanf("%lld",&n);
    S.init(pow(n,0.667));
    int ans=0;
    for(ll l=1,r,sl=0;l<=n;l=r+1){
        r=n/(n/l);
        int sr=G(r);
        ans=(ans+(sr-sl)*1ll*S(n/l))%mod;
        sl=sr;
    }
    cout<<((ans+mod)*2ll+S(n))%mod<<endl;
}

posted @ 2020-12-25 09:04  破壁人五号  阅读(96)  评论(0编辑  收藏  举报