• [51Nod 1222]


    题面

    k=abi=1kj=1i[lcm(i,j)==k]largesum_{k=a}^bsum_{i=1}^ksum_{j=1}^i[lcm(i,j)==k]
    1<=a<=b<=10111<=a<=b<=10^{11}

    题目分析

    f(n)=i=1nj=1i[lcm(i,j)==n]large f(n)=sum_{i=1}^nsum_{j=1}^i[lcm(i,j)==n]
    Ans=i=abf(i)large Ans=sum_{i=a}^bf(i)
    f(n)=i=1nj=1i[ij==n(i,j)]=dndidj,j<=i[ij==nd && (id,jd)==1]=dni=1ndj=1i[ij==nd && (i,j)==1]=dni=1dj=1i[ij==d && (i,j)==1]=dnh(d)large f(n)=sum_{i=1}^nsum_{j=1}^i[icdot j==ncdot (i,j)]\=sum_{d|n}sum_{d|i}sum_{d|j,j<=i}[icdot j==nd~&&~(frac id,frac jd)==1]\=sum_{d|n}sum_{i=1}^{frac nd}sum_{j=1}^i[ij==frac nd~&&~(i,j)==1]\=sum_{d|n}sum_{i=1}^dsum_{j=1}^i[ij==d~&&~(i,j)==1]\=sum_{d|n}h(d)
    此处h(d)h(d)表示小于等于dd中,满足两个数互质且乘积为dd的无序数对的个数,显然
    h(d)={1 , d=12ω(d)1 , d=i=1ω(d)piailarge h(d)=left{ egin{aligned} &1~,~d=1\ &2^{omega(d)-1}~,~d=prod_{i=1}^{omega(d)}p_i^{a_i}\ end{aligned} ight.其中ω(d)largeomega(d)表示d的质因子个数

    相当于把d的质因数分成两部分,所以就每个质因数选或不选,又因为是无序数对,所以除以2,也可以写为以下形式
    h(d)=2ω(d)+[d==1]2large h(d)=frac{2^{omega(d)}+[d==1]}2

    • 有没有发现十分类似某个等式,记与nn互质的数的和为a(n)a(n)(随便选的字母),则
    • a(n)=φ(n)n+[n==1]2a(n)=frac{varphi(n)n+[n==1]}2

    回到这道题,有f(n)=dnh(d)=dn2ω(d)+[d==1]2=1+dn2ω(d)2large f(n)=sum_{d|n}h(d)=sum_{d|n}frac{2^{omega(d)}+[d==1]}2\=frac{1+sum_{d|n}2^{omega(d)}}2
    然后我们又发现其实2ω(d)large2^{omega(d)}是每个质因数选或不选的方案数,及dd的无平方因子的约数的个数,所以2ω(d)=kdμ(k)large 2^{omega(d)}=sum_{k|d}|mu(k)|根据μmu函数的定义,我们知道只有无平方因子数的函数值才为1或-1,所以加上绝对值就成了计数
    i=1nf(i)=n+i=1ndi2ω(d)2=n+i=1ndikdμ(k)2large herefore sum_{i=1}^nf(i)=frac{n+sum_{i=1}^nsum_{d|i}2^{omega(d)}}2=frac{n+sum_{i=1}^nsum_{d|i}sum_{k|d}|mu(k)|}2
    i=1ndikdμ(k)=k=1nμ(k)kddi1=k=1nμ(k)kdnd=k=1nμ(k)d=1nkndk=k=1nμ(k)d=1nknkd=k=1nμ(k)d=1nknkdlargeecause sum_{i=1}^nsum_{d|i}sum_{k|d}|mu(k)|=sum_{k=1}^n|mu(k)|sum_{k|d}sum_{d|i}1\=sum_{k=1}^n|mu(k)|sum_{k|d}lfloorfrac nd floor\=sum_{k=1}^n|mu(k)|sum_{d=1}^{lfloorfrac nk floor}lfloorfrac n{dk} floor\=sum_{k=1}^n|mu(k)|sum_{d=1}^{lfloorfrac nk floor}lfloorfrac {lfloorfrac nk floor}d floor\=sum_{k=1}^n|mu(k)|sum_{d=1}^{lfloorfrac nk floor}lfloorfrac {lfloorfrac nk floor}d floor

    • 先看第二个largesum,对于某一个nklarge{lfloorfrac nk floor}的取值,把它记作NN,就以NN的范围做整除分块优化,Θ(N)largeTheta(sqrt N)的时间复杂度,那么外层还有一个求和,于是在外面也套一层整除分块优化,预处理出前n23large n^{frac 23}后时间复杂度为Θ(n23)largeTheta(n^{frac23})

      • 此处预处理为线性筛,考虑变换,i=1nnilargesum_{i=1}^nlarge{lfloorfrac ni floor}实际可看作枚举ii后看nn以内有多少个数能被ii整除,这不就是i=1nσ0(i)largesum_{i=1}^nsigma_0(i)吗?(这个函数表示i的约数个数)
        于是我们只需要筛出约数个数在累加就行了,线性筛时存一下当前数的最小质因子的次数就可以愉快的线性筛了
    • 由于在外面一层套上了整除分块优化,则需要求出μ(k)large |mu(k)|的前缀和,也就是nn以内的无平方因子数

      • 这里处理无平方因子数时用容斥原理,有
        i=1nμ(i)=i=1nμ(i)ni2largesum_{i=1}^n|mu(i)|=sum_{i=1}^{sqrt n}mu(i)cdotlfloorfrac n{i^2} floor想想μmu函数的定义,这个容斥还是比较好理解的
        Θ(n)large Theta(sqrt n)可处理出来
    • 其实这道题用的是[SPOJ] DIVCNT2 - Counting Divisors (square)一模一样的方法(我后面的分析都是直接粘的233)

    • 但是奈何这道题TMcolor{white}TM的卡内存!(各种预处理+卡内存我只能做到6015ms>6000ms T了…)

    • 只能想想别的办法(也许有些同学掌握特殊的卡常技巧能过A掉吧)

    .
    .
    .
    .
    .
    好的。

    正文开始

    那么我就要开始略讲一点了

    定义F(i)=x=1iy=1x[xy(x,y)==i]large F(i)=sum_{x=1}^isum_{y=1}^x[frac{xy}{(x,y)}==i]
    Ans=i=1bF(i)i=1a1F(i)large Ans=sum_{i=1}^bF(i)-sum_{i=1}^{a-1}F(i)

    考虑i=1nF(i)sum_{i=1}^nF(i)怎么求
    (x,y)=r,x=ar,y=br(x,y)=r,x=ar,y=br,则
    i=1nF(i)=x=1ny=1x[xyrn]=abr[ab][(a,b)==1][abrn]large sum_{i=1}^nF(i)=sum_{x=1}^nsum_{y=1}^x[frac {xy}rle n]\=sum_asum_bsum_r[ale b][(a,b)==1][abrle n]反演一下得到i=1nF(i)=d=1nμ(d)abr[ab][abrnd2]large sum_{i=1}^nF(i)=sum_{d=1}^{sqrt n}mu(d)sum_asum_bsum_r[ale b][abrle lfloorfrac n{d^2} floor]不考虑[ab][ale b]的话就是a,b,ra,b,r三个数的乘积的统计,做法为统计xyz && xyzNxle yle z~&&~xyzle N(x,y,z)(x,y,z)数对的数量

    分别考虑三个数不相等/两个数相等/三个数相等的情况再分别乘上排列系数

    由于这样的枚举只需要枚举xN13large xle N^{frac 13},在枚举xyNxlarge xle yle frac Nx,然后Θ(1)Theta(1)统计zz的个数

    [ab][ale b]比较讨厌,假设(a,b)(a,b)(b,a)(b,a)被统计两次,因为有a=ba=b的情况不能直接除以22
    回到原问题,当a=ba=b时,由于(a,b)=1(a,b)=1,所以a=b=1a=b=1,此时rrnn种取值,所以只需要在算出的结果加上nn再除以22即可
    参考自 51Nod 题解1楼

    时间复杂度证明

    T(n)T(n)表示统计满足xyz<=nxyz<=n(x,y,z)(x,y,z)的三元组个数的时间复杂度
    T(n)=Θ(x=1n13(nxx))=Θ(n23)large T(n)=Thetaleft(sum_{x=1}^{n^{frac 13}}(sqrt{frac nx}-x) ight)=Theta(n^{frac 23})
    上面的x-x是枚举yy时从x+1x+1开始枚举,总时间复杂度=Θ(d=1nT(nd2))=Θ(d=1nT((nd)2))=Θ(d=1n(nd)43)=Θ(d=1n(n23d43))=Θ(n23d=1n(1d43))large =Thetaleft(sum_{d=1}^{sqrt n}T(frac n{d^2}) ight)\=Thetaleft(sum_{d=1}^{sqrt n}T((frac{sqrt n}d)^2) ight)\=Thetaleft(sum_{d=1}^{sqrt n}(frac{sqrt n}d)^{frac 43} ight)\=Thetaleft(sum_{d=1}^{sqrt n}(frac{n^{frac 23}}{d^{frac 43}}) ight)\=Thetaleft(n^{frac 23}sum_{d=1}^{sqrt n}(frac{1}{d^{frac 43}}) ight)此处dd的枚举应该是离散的,我们将它看做连续的,由于n=n12sqrt n=n^{frac 12}那么将dd两两结合,有
    1n14(1x43)+(1(n12x34))dx>=1n142(1x43(n12x34))dx=1n142(1n12)dxlargeint_{1}^{n^{frac 14}} (frac 1{x^{frac 43}})+(frac 1{(frac{n^{frac 12}}{x^{frac 34}})})dx\>=int_{1}^{n^{frac 14}} 2left(frac 1{x^{frac 43}{(frac{n^{frac 12}}{x^{frac 34}})}} ight)dx\=int_{1}^{n^{frac 14}} 2left(frac 1{n^{frac 12}} ight)dx于是我们又回到离散的,最多有n122frac{n^frac 12}2对这样的关系,所以
    d=1n(1d43)=n1222(1n12)=1large sum_{d=1}^{sqrt n}(frac{1}{d^{frac 43}})=frac{n^frac 12}2cdot2left(frac 1{n^{frac 12}} ight)=1所以总时间复杂度为Θ(n23d=1n(1d43))=Θ(n23)large Thetaleft(n^{frac 23}sum_{d=1}^{sqrt n}(frac{1}{d^{frac 43}}) ight)=Theta(n^{frac 23})
    申明:以上的int符号纯属乱用,只是不能再用sum表示xx的取值可能不为整数的和了

    AC code
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N = 316228;
    int Cnt, Prime[N], mu[N];
    bool IsnotPrime[N];
    
    void init()
    {
    	mu[1] = 1;
    	for(int i = 2; i < N; ++i)
    	{
    		if(!IsnotPrime[i])
    			Prime[++Cnt] = i, mu[i] = -1;
    		for(int j = 1; j <= Cnt && i * Prime[j] < N; ++j)
    		{
    			IsnotPrime[i * Prime[j]] = 1;
    			if(i % Prime[j] == 0) { mu[i * Prime[j]] = 0; break; }
    			mu[i * Prime[j]] = -mu[i];
    		}
    	}
    }
    
    LL solve(LL n)
    {
    	LL ret = n;
    	for(int d = 1; (LL)d*d <= n; ++d) if(mu[d])
    	{
    		LL m = n/((LL)d*d), s = 0;
    		for(int a = 1; (LL)a*a*a <= m; ++a)
    		{
    			for(int b = a+1; (LL)a*b*b <= m; ++b)
    				s += (m/((LL)a*b)-b) * 6 + 3; // * 6 -> a < b < c ( P(3,3) = 6 )
    												// + 3 -> a < b = c ( P(3,3)/P(2,2) = 3)
    			s += (m/((LL)a*a)-a) * 3 + 1; // * 3 -> a = b < c ( P(3,3)/P(2,2) = 3 )
    											// + 1 -> a = b = c
    		}//以上的"-b","-a"都是为了满足 c>b 或 c>b=a,跟时间复杂度的分析一样
    		ret += s * mu[d];
    	}
    	return ret / 2;
    }
    
    int main ()
    {
    	LL a, b; init();
    	scanf("%lld%lld", &a, &b);
    	printf("%lld
    ", solve(b)-solve(a-1));
    }
    

    .
    .
    可写死我了

  • 相关阅读:
    安装@vuecli "失败"
    随缘更新codeforces题解
    四边形不等式
    斯特林数与幂
    待补队列
    IOC容器Autofac的另类使用
    Qt4.x 手工编译及集成到VS2010
    发段代码,验证码,很久以前的,拿出来共享啦。
    WCF 第六章 序列化和编码 总结
    WCF 第六章 序列化与编码之XmlSerializer
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039456.html
Copyright © 2020-2023  润新知