类欧几里得算法
首先推一下可以发现,我们可以分“位”计算。
设二进制下第\(k\)对答案的贡献为\(\mathrm{Ans_k}\),则
最后一步相当于第\(k\)之前的内容消掉。
然后就引出了一个通用的问题:如何快速地求出\(\sum\limits_{i=0}^{n}\left \lfloor \dfrac{ai+b}{c} \right \rfloor\)的值。
首先我们可以先算一下\(\sum\limits_{i=0}^{n}\left \lfloor \dfrac{ai+b}{c} \right \rfloor\)的值(因为类欧的下标就是从\(0\))开始的。
(设\(f(a,b,c,n)=\sum\limits_{i=0}^{n} \left \lfloor \dfrac{ai+b}{c} \right \rfloor\))
\(\left \lfloor \dfrac{ai+b}{c} \right \rfloor\)可能是个假分数,所以我们可以把它拆成一个带分数。
设\(a'=a \mod c\),\(b'=b \mod c\)。
则
对于\(a<c,b<c\)的情况,我们就再次乱搞。
(设\(m=\left \lfloor \dfrac{an+b}{c} \right \rfloor\))
那么$f(a,b,c,n) =\sum\limits_{i=0}{n}\sum\limits_{j=1} [\left \lfloor \dfrac{ai+b}{c} \right \rfloor \geqslant j ] $
这一步貌似把原式变复杂了,但是接下来就会发觉这是有用的。
接着,我们把\(j\)的下标改一改:$\sum\limits_{i=0}{n}\sum\limits_{j=0} [\left \lfloor \dfrac{ai+b}{c} \right \rfloor \geqslant j+1 ] $
很好,接下来就开始秀操作了。
将求和符号右边的式子转换一下,得$\sum\limits_{i=0}{n}\sum\limits_{j=0} [i \geqslant \dfrac{jc+c-b}{a} ] $
把第一个求和符号去掉(因为方框里面那个只是\(bool\)变量,完全可以换成差式),再把不等式的符号改成大于号,得
$\sum\limits_{j=0}^{m-1} n- \left \lfloor \dfrac{jc+c-b-1}{a} \right \rfloor $
这里多了个\(-1\)是因为$x \geqslant y \Rightarrow x>y-1 $,然后向下取整消失了又出现是正确的,这里真的不想解释。
然后有没有发现$\left \lfloor \dfrac{jc+c-b-1}{a} \right \rfloor \(和\)f$的定义很像?
没错!这就说明我们的变换成功了!
将上面式子中的\(n\)提出求和符号,再将\(f\)代入,得
\(nm-f(c,c-b-1,a,m-1)\)
所以这就是类欧。
当然了,类欧的基本式子还可以加上指数和系数,这个有空再更。