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


    题目链接

    题意

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

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

    题解

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

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

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

    记:

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

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

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

    问题化为:

    [egin{aligned} &sum_{p,q,x,y}[pot q][xy(p^2+q^2)leq n]px\ =&sum_{i=1}^{n} left(sum_{p^2+q^2=i}[pot q]p ight)+left(sum_{xyleq n /i}x ight)\ =&sum_{i=1}^{n}g(i)S(lfloor dfrac{x}{i} floor) end{aligned} ]

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

    [egin{aligned} sum_{i=1}^n g(i)=&sum_{p^2+q^2leq n}[pot q]p\ &sum_{i=1}^{sqrt n}imu(i)sum_{j=1}^{lfloor frac{n}{i^2} floor}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;
    }
    
    
    知识共享许可协议
    若文章内无特别说明,公开文章采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
  • 相关阅读:
    Git上手:四种常见的Git协同工作方式
    Git上手:Git扫盲区
    理解web缓存
    浅谈对技术债的理解
    保护个人隐私,从我做起
    cookie注意事项
    了解JavaScript核心精髓(二)
    简单实现nodejs爬虫工具
    浅谈我所见的CSS组织风格
    利用正则表达式清除多余的空行
  • 原文地址:https://www.cnblogs.com/wallbreaker5th/p/14187283.html
Copyright © 2020-2023  润新知