【瞎讲】类欧几里得入土教程
【瞎讲】类欧几里得入土教程
产生背景
假设我们现在得到一条直线\(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}\rfloor
\]
考虑如何快速计算这个式子,我们考虑如何化为子问题
前置芝士
向下取整有这一个性质(其他性质可以由此推出):
\[\lfloor \dfrac {a+c} b\rfloor=\lfloor \dfrac {a\%b+\lfloor\dfrac a b\rfloor b+c}{b}\rfloor=\lfloor \dfrac {a\%b+c}{b}\rfloor + \lfloor\dfrac a b\rfloor
\]
然后有两个重要而显然的性质:
\[\lfloor {a\over b}\rfloor \le {a\over b}
\]
类似的
\[\lceil {a\over b}\rceil \ge {a\over b}
\]
还有相互转换法则
\[\lfloor {a\over b} \rfloor =\lceil {a-b+1\over b} \rceil
\]
类似的
\[\lceil {a\over b} \rceil = \lfloor{a+b-1 \over b}\rfloor
\]
我觉得不用解释了吧...
解决问题
有了上面的芝士,我们考虑
\[\sum_{i=0}^n \lfloor \dfrac {ai+b}{c}\rfloor
\]
时,稍微化归一下:
-
\(a\ge c\)时
\[\]\[\] -
\(b\ge c\)时
同样的
\[\]\[ \]
现在就只要计算\(a,b< c\)的情况即可,进行一波和式变换
\[\sum_{i=0}^n \lfloor {ai+b \over c} \rfloor
\]
创造条件
\[=\sum_{i=0}^n \sum_{j=1}^{\lfloor {ai+b \over c} \rfloor} 1
\]
和式套路
\[= \sum_{i=0}^n\sum_{j=1}^{\lfloor {an+b \over c} \rfloor} [j \le \lfloor {ai+b \over c} \rfloor]=\sum_{j=1}^{\lfloor {an+b \over c} \rfloor} \sum_{i=0}^n [j \le \lfloor {ai+b \over c} \rfloor]
\]
根据前置芝士
\[=\sum_{j=1}^{\lfloor {an+b \over c} \rfloor} \sum_{i=0}^n [cj \le {ai+b} ]
\]
考虑\(i\)
\[=\sum_{j=1}^{\lfloor {an+b \over c} \rfloor} \sum_{i=0}^n [cj-b \le ai ]
\]
根据前置芝士
\[=\sum_{j=1}^{\lfloor {an+b \over c} \rfloor} \sum_{i=0}^n [\lceil{cj-b\over a}\rceil \le i ]
\]
此时可以直接算出来第二个\(\Sigma\)的值
\[=\sum_{j=1}^{\lfloor {an+b \over c} \rfloor} (n-\lceil{cj-b\over a}\rceil+1)
\]
根据前置芝士
\[=\sum_{j=1}^{\lfloor {an+b \over c} \rfloor} (n-\lfloor{cj-b+a-1\over a}\rfloor+1)
\]
提出来
\[=(n+1)\lfloor {an+b \over c} \rfloor -\sum_{j=1}^{\lfloor {an+b \over c} \rfloor} \lfloor{cj-b+a-1\over a}\rfloor
\]
后面就是一个子问题啊!问题规模降了一半以上(当\(c=1\)的时候可以直接等差数列求和\(O(1)\)算)
所以解决原问题的复杂度为
\[T(n)\le O(1)+T({n \over 2})
\]
根据主定理
\[T(n)\le \log_2 n
\]
那么问题来了,为啥叫做类欧几里得算法呢?因为复杂度证明是相似的...滑稽
博客保留所有权利,谢绝学步园、码迷等不在文首明显处显著标明转载来源的任何个人或组织进行转载!其他文明转载授权且欢迎!