zoukankan      html  css  js  c++  java
  • 【瞎讲】类欧几里得入土教程

    【瞎讲】类欧几里得入土教程

    产生背景

    假设我们现在得到一条直线(y=ax+b),现在要数出(x in [0,n])时,在(x)正半轴和这条直线之间的整点个数,(n le 10^{18})

    解决思路

    这个方程一定可以化为这样的形式

    [y=dfrac {ax+b}{c} ]

    枚举(x in [0,n]),直接算其整点个数,答案就是

    [sum_{i=0}^n lfloor dfrac {ai+b}{c} floor ]

    考虑如何快速计算这个式子,我们考虑如何化为子问题

    前置芝士

    向下取整有这一个性质(其他性质可以由此推出):

    [lfloor dfrac {a+c} b floor=lfloor dfrac {a\%b+lfloordfrac a b floor b+c}{b} floor=lfloor dfrac {a\%b+c}{b} floor + lfloordfrac a b floor ]

    然后有两个重要而显然的性质:

    [lfloor {aover b} floor le {aover b} ]

    类似的

    [lceil {aover b} ceil ge {aover b} ]

    还有相互转换法则

    [lfloor {aover b} floor =lceil {a-b+1over b} ceil ]

    类似的

    [lceil {aover b} ceil = lfloor{a+b-1 over b} floor ]

    我觉得不用解释了吧...

    解决问题

    有了上面的芝士,我们考虑

    [sum_{i=0}^n lfloor dfrac {ai+b}{c} floor ]

    时,稍微化归一下:

    • (age c)

      []

      []

    • (bge c)

      同样的

      []

      [ ]

    现在就只要计算(a,b< c)的情况即可,进行一波和式变换

    [sum_{i=0}^n lfloor {ai+b over c} floor ]

    创造条件

    [=sum_{i=0}^n sum_{j=1}^{lfloor {ai+b over c} floor} 1 ]

    和式套路

    [= sum_{i=0}^nsum_{j=1}^{lfloor {an+b over c} floor} [j le lfloor {ai+b over c} floor]=sum_{j=1}^{lfloor {an+b over c} floor} sum_{i=0}^n [j le lfloor {ai+b over c} floor] ]

    根据前置芝士

    [=sum_{j=1}^{lfloor {an+b over c} floor} sum_{i=0}^n [cj le {ai+b} ] ]

    考虑(i)

    [=sum_{j=1}^{lfloor {an+b over c} floor} sum_{i=0}^n [cj-b le ai ] ]

    根据前置芝士

    [=sum_{j=1}^{lfloor {an+b over c} floor} sum_{i=0}^n [lceil{cj-bover a} ceil le i ] ]

    此时可以直接算出来第二个(Sigma)的值

    [=sum_{j=1}^{lfloor {an+b over c} floor} (n-lceil{cj-bover a} ceil+1) ]

    根据前置芝士

    [=sum_{j=1}^{lfloor {an+b over c} floor} (n-lfloor{cj-b+a-1over a} floor+1) ]

    提出来

    [=(n+1)lfloor {an+b over c} floor -sum_{j=1}^{lfloor {an+b over c} floor} lfloor{cj-b+a-1over a} floor ]

    后面就是一个子问题啊!问题规模降了一半以上(当(c=1)的时候可以直接等差数列求和(O(1))算)

    所以解决原问题的复杂度为

    [T(n)le O(1)+T({n over 2}) ]

    根据主定理

    [T(n)le log_2 n ]

    那么问题来了,为啥叫做类欧几里得算法呢?因为复杂度证明是相似的...滑稽

  • 相关阅读:
    GO学习之 为什么选择GO
    Flask学习之 Jinja2模板引擎
    排序算法之归并排序的python实现
    排序算法之快速排序的python实现
    排序算法之希尔排序的python实现
    排序算法之插入排序的python实现
    排序算法之选择排序的python实现
    Android 中正则表达式工具类
    java之从字符串比较到==和equals方法区别
    Android Studio酷炫插件(一)——自动化快速实现Parcelable接口序列化
  • 原文地址:https://www.cnblogs.com/winlere/p/11352880.html
Copyright © 2011-2022 走看看