• 学习类欧几里得小记


    首先

    我们设mod表示取模(%)
    我们设[]表示当括号内判断条件为真则退出1,否则退出0

    关于欧几里得

    对于b<>0 满足:gcd(a,b)=gcd(b,a % b)
    证明与时间复杂度不多说了吧?
    在这里插入图片描述
    复杂度证明贴上,看不懂也不怪我了。

    关于类欧几里得

    这个实际上是用欧几里得的时间复杂度与计算方法来弄的一种奇妙的算法。
    我们看一道题:
    求:d=1n(1)drdsum_{d=1}^{n}(-1)^{lfloor sqrt{d*r*d} floor}
    那么,我们可以发现,只要确定drd{lfloor sqrt{d*r*d} floor}是不是偶数即可。
    那么原式就转化为:d=1nrd/2mod2sum_{d=1}^{n}lfloor sqrt{r}*d/2 floor mod 2
    据说这个东东可以利用几何来搞。
    大致就是在二维平面上,根据rsqrt{r}dd 来弄个直线。
    然后确定覆盖的值即可。

    然而局限性很大,不好用。

    我们考虑一般形式(也就是类欧的基本形式)
    x=0n(xa+b)/csum_{x=0}^{n}lfloor (x*a+b)/c floor
    于是我们就要将这个式子的计算弄成O(log)O(log)的时间复杂度。
    这就是类欧

    求解

    我们首先设三个函数:
    f(a,b,c,n)=x=0n(xa+b)/cf(a,b,c,n)=sum_{x=0}^{n}lfloor (x*a+b)/c floor
    g(a,b,c,n)=x=0nx(xa+b)/cg(a,b,c,n)=sum_{x=0}^{n} x*lfloor (x*a+b)/c floor
    h(a,b,c,n)=x=0n((xa+b)/c)2h(a,b,c,n)=sum_{x=0}^{n}(lfloor (x*a+b)/c floor)^2
    边界条件:当a=0时返回0.
    那么我们就要来化简式子了。
    一、看到f

    • 当a>=c时
      • x=0n(xa+b)/csum_{x=0}^{n}lfloor (x*a+b)/c floor
      • =x=0n(x(a=sum_{x=0}^{n}lfloor (x*(a modmod c)+b)/c+xa/cc)+b)/c floor+x*lfloor a/c floor
      • =(n+1)na/c/2+x=0n(x(a=(n+1)*n*lfloor a/c floor/2+sum_{x=0}^{n}lfloor (x*(a modmod c)+b)/cc)+b)/c floor
      • =(n+1)na/c/2+f(a=(n+1)*n*lfloor a/c floor/2+f(a modmod c,b,c,n)c,b,c,n)
      • 恭喜时间缩短一个log。
    • 当b>=c时
      • x=0n(xa+b)/csum_{x=0}^{n}lfloor (x*a+b)/c floor
      • =x=0n(xa+(b=sum_{x=0}^{n}lfloor (x*a+(b modmod c))/c+b/cc))/c floor+lfloor b/c floor
      • =nb/c+x=0n(xa+(b=n*lfloor b/c floor+sum_{x=0}^{n}lfloor (x*a+(b modmod c))/cc))/c floor
      • =nb/c+f(a,b=n*lfloor b/c floor+f(a,b modmod c,c,n)c,c,n)
      • 恭喜时间再缩短一个log。
    • 当 a<c 且 b<c 时
      • 首先我们设m=(ax+b)/cm=lfloor (a*x+b)/c floor
      • 那么原式就转化为:x=0ny=1m[y&lt;(ax+b)/c]sum_{x=0}^{n}sum_{y=1}^{m}[y&lt;lfloor (a*x+b)/c floor]
      • 于是我们把y&lt;(ax+b)/cy&lt;lfloor (a*x+b)/c floor拆出来看看
      • y+1(ax+b)/c(ax+b)/cy+1le lfloor (a*x+b)/c floor le (a*x+b)/c
      • c(y+1)ax+bc*(y+1) le a*x+b
      • cy+cb1&lt;axc*y+c-b-1 &lt;a*x
      • (cy+cb1)/a&lt;xlfloor (c*y+c-b-1)/a floor&lt;x
      • 那么带入原式就变成了y=0m1x=0n[(cy+cb1)/a&lt;x]sum_{y=0}^{m-1}sum_{x=0}^{n}[lfloor (c*y+c-b-1)/a floor&lt;x]
      • y=0m1n(cy+cb1)/asum_{y=0}^{m-1} n-lfloor (c*y+c-b-1)/a floor
      • n(m+1)y=0m1(cy+cb1)/an*(m+1)-sum_{y=0}^{m-1} lfloor (c*y+c-b-1)/a floor
      • n(m+1)f(c,cb1,a,m1)n*(m+1)-f(c,c-b-1,a,m-1)

    那么f就推完了
    二、看到g

    • 当a>=c时,好推,思路和f相近
      • =x=0nx(x(a=sum_{x=0}^{n}x*lfloor (x*(a modmod c)+b)/c+x2a/cc)+b)/c floor+x^2*lfloor a/c floor
      • =(2n+1)(n+1)na/c/6+x=0nx(x(a=(2*n+1)(n+1)*n*lfloor a/c floor/6+sum_{x=0}^{n}x*lfloor (x*(a modmod c)+b)/cc)+b)/c floor
      • 注意,那条奇怪的n的式子是用平方和公式计算出来的,不懂的百度一下“平方和公式”
      • =(2n+1)(n+1)na/c/6+g(a=(2*n+1)(n+1)*n*lfloor a/c floor/6+g(a modmod c,b,c,n)c,b,c,n)
    • 当b>=c时,也好推,思路也相似,就直接贴答案了吧。
      • =(n+1)nb/c/2+g(a,b=(n+1)*n*lfloor b/c floor/2+g(a,b modmod c,c,n)c,c,n)
    • 当a<c且b<c时,我们就也是类似于f,只不过有点麻烦。
      • 我们同样的把原式拆成x=0nxy=1m[(cy+cb1)/a&lt;x]sum_{x=0}^{n}x*sum_{y=1}^{m}[lfloor (c*y+c-b-1)/a floor&lt;x]
      • 设T=(cy+cb1)/alfloor (c*y+c-b-1)/a floor
      • 那么,我们可以移动一下式子:
      • y=0mx=0n[T&lt;x]xsum_{y=0}^{m}sum_{x=0}^{n}[T&lt;x]*x
      • y=0mx=T+1nxsum_{y=0}^{m}sum_{x=T+1}^{n}x
      • 利用求和公式:y=0m1(n+1+t)(nT)/2sum_{y=0}^{m-1}(n+1+t)*(n-T)/2
      • 化简:y=0m1((n+1)nTT2)/2sum_{y=0}^{m-1}((n+1)*n-T-T^2)/2
      • 逐个拆开来看,答案就是:
      • nm(n+1)/2h(c,cb1,a,m1)/2f(c,cb1,a,m1)/2n*m*(n+1)/2-h(c,c-b-1,a,m-1)/2-f(c,c-b-1,a,m-1)/2

    那么g也推完了,但是我们看到有个h在式子中,怎么办?
    三、看到h

    • 对于a>=c或b>=c我们设H=a/cH=lfloor a/c floor E=b/cE=lfloor b/c floor
      • 那么我们开始拆式子:
      • x=0n((xa+b)/c)2sum_{x=0}^n(lfloor (x*a+b)/c floor)^2
      • =x=0n((x(a=sum_{x=0}^n(lfloor (x*(a modmod c)+(bc)+(b modmod c))/c+xH+E)2c))/c floor+x*H+E)^2
      • =x=0n((x(a=sum_{x=0}^n(lfloor (x*(a modmod c)+(bc)+(b modmod c))/c)2+2(xH+E)((x(ac))/c floor)^2+2*(x*H+E)*(lfloor (x*(a modmod c)+(bc)+(b modmod c))/c)+(xH+E)2c))/c floor)+(x*H+E)^2
      • =x=0n((x(a=sum_{x=0}^n(lfloor (x*(a modmod c)+(bc)+(b modmod c))/c)2+2xH((x(ac))/c floor)^2+2*x*H*(lfloor (x*(a modmod c)+(bc)+(b modmod c))/c)+2E((x(ac))/c floor)+2*E*(lfloor (x*(a modmod c)+(bc)+(b modmod c))/c)+(xH+E)2c))/c floor)+(x*H+E)^2
      • =h(a=h(a modmod c,bc,b modmod c,c,n)c,c,n)
      • +2Hg(a+2*H*g(a modmod c,bc,b modmod c,c,n)c,c,n)
      • +2Ef(a+2*E*f(a modmod c,bc,b modmod c,c,n)c,c,n)
      • +n(n+1)(2n+1)H2/6+n(n+1)HE+(n+1)E2+n*(n+1)*(2*n+1)*H^2/6+n*(n+1)*H*E+(n+1)*E^2
      • 我们发现,当a<c或b<c时,H或E会等于0,所以不会影响答案
    • 对于a<c且b<c时,我们就另辟西路。
      • 我们首先看到这个转化:
      • n2=2(n+1)n/2n=(2i=1ni)nn^2=2*(n+1)*n/2-n=(2*sum_{i=1}^ni)-n
      • 那么我们就可以再来愉快地推式子啦。
      • T=(ax+b)/cM=(an+b)/cT=lfloor (a*x+b)/c floor M=lfloor (a*n+b)/c floor
      • =x=0n((2y=1Ty)T)原式=sum_{x=0}^n((2*sum_{y=1}^Ty)-T)
      • =x=0n((2z=0M1(z+1)[T&gt;=z+1])T)=sum_{x=0}^n((2*sum_{z=0}^{M-1}(z+1)*[T&gt;=z+1])-T)
      • (这里M-1是因为后面的z+1)
      • 我们把那条又臭又熟悉的式子拆出来。
      • P=(cy+cb1)/aP=lfloor (c*y+c-b-1)/a floor
      • =x=0n((2z=0M1(z+1)[x&gt;P])T)=sum_{x=0}^n((2*sum_{z=0}^{M-1}(z+1)*[x&gt;P])-T)
      • =2(z=0M1z(np)+z=0M1(np))f(a,b,c,n)=2*(sum_{z=0}^{M-1}z*(n-p)+sum_{z=0}^{M-1}(n-p))-f(a,b,c,n)
      • =nM(M+1)2g(c,cb1,a,M1)2f(c,cb1,a,M1)f(a,b,c,n)=n*M*(M+1)-2*g(c,c-b-1,a,M-1)-2*f(c,c-b-1,a,M-1)-f(a,b,c,n)

    至此,式子已经推完。
    可以看看例题:陶陶的难题。

    我活在这夜里。无论周围多么黑暗,我都要努力发光!我相信着,终有一天,我会在这深邃的夜里,造就一道最美的彩虹。
  • 相关阅读:
    Python time ctime()方法
    Python time clock()方法
    Python time asctime()方法
    Python time altzone()方法
    Python 日期和时间
    java——字符串常量池、字符串函数以及static关键字的使用、数组的一些操作函数、math函数
    java——API
    java——类、对象、private、this关键字
    Java——方法及构造方法、intellij IDEA中的一些快捷键
    IntelliJ IDEA 运行java程序时出现“程序发生找不到或无法加载主类 cn.test1.test1”错误
  • 原文地址:https://www.cnblogs.com/RainbowCrown/p/11148383.html
Copyright © 2020-2023  润新知