• 类欧几里得算法


    当我们要计算形如

    [ sum_{i=0}^nlfloor frac{ai+b}{c} floor ]

    且a,b>=0,c>0时
    可以使用类欧算法。

    首先有以下公式

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

    [lfloorfrac{a}{b} floor = lceil frac{a-b+1}{b} ceil ]

    挺容易推的:关于1式,如果 a % b != 0,那么右边就会比左边大1,2式原理相同。

    然后开始推(?
    我们令

    [F(a,b,c,n)=sum_{i=0}^nlfloor frac{ai+b}{c} floor ]

    [{a}geq{c}Rightarrowsum_{i=0}^nlfloor frac{ai+b}{c} floor=sum_{i=0}^n(lfloor frac{a\%c imes i+b}{c} floor+lfloorfrac{a}{c} floor i)=sum_{i=0}^nlfloor frac{a\%c imes i+b}{c} floor+lfloorfrac{a}{c} floorfrac{n imes (n+1)}{2} ]

    [{b}geq{c}Rightarrowsum_{i=0}^nlfloor frac{ai+b}{c} floor=sum_{i=0}^nlfloor frac{a i+b\% c}{c} floor+lfloorfrac{b}{c} floor(n+1) ]

    因此

    [{a}geq{c}||{b}geq{c}Rightarrowsum_{i=0}^nlfloor frac{ai+b}{c} floor=sum_{i=0}^nlfloor frac{(a\%c) i+b\% c}{c} floor+lfloorfrac{b}{c} floor(n+1)+lfloorfrac{a}{c} floorfrac{n imes (n+1)}{2} ]

    [Rightarrow F(a,b,c,n) = F(a\%c,b\%c,c,n)++lfloorfrac{b}{c} floor(n+1)+lfloorfrac{a}{c} floorfrac{n imes (n+1)}{2} ]

    之后只要解决(a lt c && blt c)的情况就好了(?

    [sum_{i=0}^nlfloor frac{ai+b}{c} floor =sum_{i=0}^nsum_{j=1}^{lfloor frac{ai+b}{c} floor}1 =sum_{i=0}^nsum_{j=1}^{lfloor frac{an+b}{c} floor}[{jleq lfloor frac{ai+b}{c} floor}] ]

    交换求和顺序(

    [Rightarrow sum_{j=1}^{lfloor frac{an+b}{c} floor}sum_{i=0}^n[{jleq lfloor frac{ai+b}{c} floor}] ]

    又有

    [lfloor frac{a}{b} floor geq c Leftrightarrow ageq bc ]

    [lceil frac{a}{b} ceil leq c Leftrightarrow aleq bc ]

    因此

    [=sum_{j=1}^{lfloor frac{an+b}{c} floor}sum_{i=0}^n[jcleq {ai+b}] =sum_{j=1}^{lfloor frac{an+b}{c} floor}sum_{i=0}^n[lceil frac{jc-b}{a} ceil leq i] =sum_{j=1}^{lfloor frac{an+b}{c} floor}[n+1-lceil frac{jc-b}{a} ceil] ]

    [=sum_{j=1}^{lfloor frac{an+b}{c} floor}[n+1-lfloor frac{jc-b+a-1}{a} floor] ]

    [=nlfloor frac{an+b}{c} floor-sum_{j=1}^{lfloor frac{an+b}{c} floor}[lfloor frac{jc-b+a-1}{a} floor-1] =nlfloor frac{an+b}{c} floor-sum_{j=0}^{lfloor frac{an+b}{c} floor-1}[lfloor frac{(j+1)c-b-1}{a} floor] ]

    因此我们有(a,blt c)

    [F(a,b,c,n)=nlfloor frac{an+b}{c} floor-F(c,-1-b+c,a,lfloor frac{an+b}{c} floor-1) ]

    然后就 可以递归了 终止条件a=0
    以下代码

      ll exgcd(ll a, ll b, ll c, ll n){
            if(a==0) return (n+1)*(b/c);
            if(a>=c||b>=c) return exgcd(a%c, b%c, c, n) + floor(a/c)*n*(n+1)/2 + floor(b/c)*(n+1);
            ll temp = (a*n+b)/c;
            return n*temp - exgcd(c, c-b-1, a, temp-1);
      }
    K-ON!!
  • 相关阅读:
    测试产品
    三年回顾
    测试服务输出业务价值
    慎用重载_2
    慎用重载_1
    ByteBuffer和String的互相转换
    线程较为深的度剖析1
    线程同步的故事描述
    Java线程同步
    TCP关闭过程
  • 原文地址:https://www.cnblogs.com/pophirasawa/p/12941304.html
Copyright © 2020-2023  润新知