• 【洛谷4466】[国家集训队] 和与积(莫比乌斯反演)


    点此看题面

    • 给定(n),求有多少对(a,b)满足(1le a<ble n)((a+b)|ab)
    • (nle2^{31}-1)

    初始推式子

    说实话,最近翻了翻数论小蓝本,于是看到这种式子首先就想到令(d=gcd(a,b))得到(a_0=frac ad,b_0=frac bd)互质。

    然后就发现原式相当于是:

    [(a_0+b_0)d|a_0b_0d^2Leftrightarrow (a_0+b_0)|a_0b_0d ]

    由于(gcd(a_0+b_0,a_0)=gcd(b_0,a_0)=1)(同理(gcd(a_0+b_0,b_0)=1)),所以我们可以直接消去整除符号右边的(a_0,b_0),得到一个非常漂亮的式子:

    [(a_0+b_0)|d ]

    考虑我们现在的几个限制:

    [egin{cases} b=b_0dle nRightarrow dlelfloorfrac n{b_0} floor\ (a_0+b_0)|dRightarrow a_0+b_0le d end{cases} ]

    综合两个条件得到(a_0+b_0lelfloorfrac n{b_0} floor)

    所以说,我们发现,(a_0,b_0,d)都应该是不超过(sqrt n)的。

    莫比乌斯反演

    根据上面的结论,答案的计算式就应该是:

    [sum_{a_0=1}^{sqrt n}sum_{b_0=a_0+1}^{sqrt n}lfloorfrac{lfloorfrac{n}{b_0} floor}{a_0+b_0} floor[gcd(a_0,b_0)=1] ]

    经典莫比乌斯反演,枚举(gcd)得到:

    [sum_{d=1}^{sqrt n}mu(d)sum_{a_0=1}^{lfloorfrac{sqrt n}d floor}sum_{b_0=a_0+1}^{lfloorfrac{sqrt n}d floor}lfloorfrac{lfloorfrac n{b_0d} floor}{(a_0+b_0)d} floor ]

    其中大分母中的(d)可以移到分子的分母中:

    [sum_{d=1}^{sqrt n}mu(d)sum_{a_0=1}^{lfloorfrac{sqrt n}d floor}sum_{b_0=a_0+1}^{lfloorfrac{sqrt n}d floor}lfloorfrac{lfloorfrac n{b_0d^2} floor}{a_0+b_0} floor ]

    我们发现(a_0)只出现在分母(a_0+b_0)这一项中,因此我们不如不枚举(a_0),而是去枚举分母,得到:

    [sum_{d=1}^{sqrt n}mu(d)sum_{b_0=2}^{lfloorfrac{sqrt n}d floor}sum_{t=b_0+1}^{2b_0-1}lfloorfrac{lfloorfrac n{b_0d^2} floor}{t} floor ]

    发现此时的(sum_{t=b_0+1}^{2b_0-1}lfloorfrac{lfloorfrac n{b_0d^2} floor}{t} floor)已经成为一个标准的除法分块形式。

    那么我们只要以共计(O(sqrt nlogsqrt n))的复杂度枚举(d,b_0),然后除法分块(O(sqrt{sqrt n}))枚举(t)即可解决此题。

    代码:(O(n^{frac34}logsqrt n))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define SN 47000
    #define LL long long
    using namespace std;
    int n,sn;struct LinearSieve
    {
    	int Pt,P[SN+5],mu[SN+5];I int operator [] (CI x) {return mu[x];}
    	I LinearSieve()//线性筛预处理μ
    	{
    		mu[1]=1;for(RI i=2,j;i<=SN;++i) for(!P[i]&&(mu[P[++Pt]=i]=-1),
    			j=1;j<=Pt&&i*P[j]<=SN;++j) if(P[i*P[j]]=1,i%P[j]) mu[i*P[j]]=-mu[i];else break;
    	}
    }Mu;
    I LL Calc(CI L,CI R,CI n)//除法分块
    {
    	RI l,r;LL t=0;for(l=L;l<=min(n,R);l=r+1) r=min(R,n/(n/l)),t+=1LL*(n/l)*(r-l+1);return t;
    }
    int main()
    {
    	RI i,j;LL t=0;for(scanf("%d",&n),sn=sqrt(n),i=1;i<=sn;++i)//枚举d
    		for(j=2;i*j<=sn;++j) t+=Mu[i]*Calc(j+1,2*j-1,n/i/i/j);return printf("%lld
    ",t),0;//枚举b0,然后除法分块
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    地图 SDK 系列教程-在地图上展示指定区域
    [奇思妙想]下一个和微博、微信同级别的应用为是什么样的
    [办公自动化]EXCEL不大,但是保存很慢
    [奇思妙想]公共图书馆+快递
    [奇思妙想]“停哪了”
    [IT学习]阿铭Linux 微信公众号 每日一题 解析
    [IT学习]GIT 学习
    [故障处理]西部数据wd elements xp 无法识别
    [奇思妙想]无人机
    [IT学习]跟阿铭学linux(第3版)
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu4466.html
Copyright © 2020-2023  润新知