本文主要是介绍类欧几里德算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
引入
设
f ( a , b , c , n ) = ∑ i = 0 n ⌊ a i + b c ⌋ f(a,b,c,n)=\sum_{i=0}^n\left\lfloor \frac{ai+b}{c} \right\rfloor f(a,b,c,n)=i=0∑n⌊cai+b⌋
考虑其几何意义,设 L : y = c a x + b L:y= \frac{c}{ax+b} L:y=ax+bc
我们要求的实际上是二维平面上 L L L, x x x轴, y y y轴和 x = n x=n x=n这4条直线围成的梯形中整点的数量。细节地说,对于边界上的点, x x x轴上的点不能取,其他三条线上的点都能取。
其中 a , b , c , n a,b,c,n a,b,c,n 是常数。需要一个 O ( log n ) O(\log n) O(logn) 的算法。
这个式子和我们以前见过的式子都长得不太一样。带向下取整的式子容易让人想到数论分块,然而数论分块似乎不适用于这个求和。但是我们是可以做一些预处理的。
如果说 a ≥ c a\ge c a≥c 或者 b ≥ c b\ge c b≥c,意味着可以将 a , b a,b a,b 对 c c c 取模以简化问题:
f ( a , b , c , n ) = ∑ i = 0 n ⌊ a i + b c ⌋ = ∑ i = 0 n ⌊ ( ⌊ a c ⌋ c + a m o d c ) i + ( ⌊ b c ⌋ c + b m o d c ) c ⌋ = n ( n + 1 ) 2 ⌊ a c ⌋ + ( n + 1 ) ⌊ b c ⌋ + ∑ i = 0 n ⌊ ( a m o d c ) i + ( b m o d c ) c ⌋ = n ( n + 1 ) 2 ⌊ a c ⌋ + ( n + 1 ) ⌊ b c ⌋ + f ( a m o d c , b m o d c , c , n ) \begin{aligned} f(a,b,c,n)&=\sum_{i=0}^n\left\lfloor \frac{ai+b}{c} \right\rfloor\\ &=\sum_{i=0}^n\left\lfloor \frac{\left(\left\lfloor\frac{a}{c}\right\rfloor c+a\bmod c\right)i+\left(\left\lfloor\frac{b}{c}\right\rfloor c+b\bmod c\right)}{c}\right\rfloor\\ &=\frac{n(n+1)}{2}\left\lfloor\frac{a}{c}\right\rfloor+(n+1)\left\lfloor\frac{b}{c}\right\rfloor+ \sum_{i=0}^n\left\lfloor\frac{\left(a\bmod c\right)i+\left(b\bmod c\right)}{c} \right\rfloor\\ &=\frac{n(n+1)}{2}\left\lfloor\frac{a}{c}\right\rfloor +(n+1)\left\lfloor\frac{b}{c}\right\rfloor+f(a\bmod c,b\bmod c,c,n) \end{aligned} f(a,b,c,n)=i=0∑n⌊cai+b⌋=i=0∑n⌊c(⌊ca⌋c+amodc)i+(⌊cb⌋c+bmodc)⌋=2n(n+1)⌊ca⌋+(n+1)⌊cb⌋+i=0∑n⌊c(amodc)i+(bmodc)⌋=2n(n+1)⌊ca⌋+(n+1)⌊cb⌋+f(amodc,bmodc,c,n)
那么问题转化为了 a < c , b < c a<c,b<c a<c,b<c 的情况。观察式子,你发现只有 i i i 这一个变量。因此要推就只能从 i i i 下手。在推求和式子中有一个常见的技巧,就是条件与贡献的放缩与转化。具体地说,在原式 f ( a , b , c , n ) = ∑ i = 0 n ⌊ a i + b c ⌋ \displaystyle f(a,b,c,n)=\sum_{i=0}^n\left\lfloor \frac{ai+b}{c} \right\rfloor f(a,b,c,n)=i=0∑n⌊cai+b⌋ 中, 0 ≤ i ≤ n 0\le i\le n 0≤i≤n 是条件,而 ⌊ a i + b c ⌋ \left\lfloor \dfrac{ai+b}{c} \right\rfloor ⌊cai+b⌋ 是对总和的贡献。
要加快一个和式的计算过程,所有的方法都可以归约为 贡献合并计算。但你发现这个式子的贡献难以合并,怎么办?将贡献与条件做转化 得到另一个形式的和式。具体地,我们直接把原式的贡献变成条件:
∑ i = 0 n ⌊ a i + b c ⌋ = ∑ i = 0 n ∑ j = 0 ⌊ a i + b c ⌋ − 1 1 \sum_{i=0}^n\left\lfloor \frac{ai+b}{c} \right\rfloor =\sum_{i=0}^n\sum_{j=0}^{\left\lfloor \frac{ai+b}{c} \right\rfloor-1}1\\ i=0∑n⌊cai+b</
这篇关于类欧几里德算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!