类欧几里得算法
类欧几里得算法
本题以 P5170 【模板】类欧几里得算法 为例,深入讲解类欧几里得算法的本质。
普通类欧几里得算法
首先,设 $f(n,a,b,c)=\sum_{i=0}^n \lfloor \frac {ai+b}{c} \rfloor$,我们想在 $\log$ 时间范围内求出这个函数的值。
首先考虑把 $a \ge c$ 或者 $b \ge c$ 的情况规约到 $a<c$ 并且 $b<c$ 的情况,容易发现,如果 $a>c$,式子可以化成这样:
$$
\sum_{i=0}^n \lfloor \frac {(a \bmod c)i+b}{c} \rfloor + \sum_{i=0}^n \lfloor \frac ac \rfloor i
$$
后面的一堆可以用等差数列的求和公式计算,如果 $b>c$,式子可以化成这样:
$$
\sum_{i=0}^n \lfloor \frac {ai+b \bmod c}{c} \rfloor+\sum_{i=0}^n \lfloor \frac bc \rfloor
$$
后面一堆可以直接计算,于是我们只需要考虑 $a<c$ 并且 $b<c$ 的情况。
我们来推一下式子:
$$
\begin{aligned}
& \ \ \ \ \ \sum_{i=0}^n \lfloor \frac {ai+b}{c} \rfloor \\
&=\sum_{i=0}^n \sum_{j=0}^{\lfloor \frac {ai+b}{c} \rfloor-1}1 \\
&= \sum_{j=0}^{\lfloor \frac {an+b}{c}\rfloor-1} \sum_{i=0}^n [j<\lfloor \frac {ai+b}{c} \rfloor]
\end{aligned}
$$
再设 $m=\frac {an+b}{c}$,则原式变为 $\sum_{j=0}^{m-1} \sum_{i=0}^n [j<\lfloor \frac {ai+b}{c} \rfloor]$。
考虑对艾佛森括号内的式子进行变换,因为两边都是整数,所以可以写成 $[j+1 \le \lfloor \frac {ai+b}{c} \rfloor]$,又因为 $c$ 一定是正整数,根据带余除法,设 $ai+b=kc+q(0 \le q<c)$,则 $\lfloor \frac {ai+b}{c} \rfloor=k$,所以两边乘 $c$ 是没有问题的,即 $[cj+c \le ai+b]$,就相当于若 $j+1 \le k$,则此式子一定成立,否则此式子一定不成立。
这时我们继续变换之后下取整得到 $cj+c \le ai+b \rightarrow cj+c-b \le ai \rightarrow cj+c-b-1<ai \rightarrow \lfloor\frac {cj+c-b-1}{a}\rfloor<i$。
代回原式,得 $\sum_{j=0}^{m-1} \sum_{i=0}^n [\lfloor \frac {cj+c-b-1}{a}\rfloor<i]$,这个函数后面一个 $\sum$ 的值我们可以简单地计算得出,所以原式变为:
$$
\sum_{j=0}^{m-1} n-\lfloor \frac {cj+c-b-1}{a} \rfloor=nm-\sum_{j=0}^{m-1} \lfloor \frac {cj+c-b-1}{a} \rfloor
$$
于是我们可以把函数写成一个常数加上另外一个函数的和,如下:
$$
f(n,a,b,c)=nm-f(m-1,c,c-b-1,a)
$$
因为每次我们都会让 $a \gets a \bmod c$,所以这个函数的计算是 $\log$ 级别的,时间复杂度分析很像欧几里得算法,故称为类欧几里得算法。
边界条件:$a=0$ 的时候函数等于 $\sum_{i=0}^n \lfloor \frac bc \rfloor$,直接计算即可,这个部分代码如下:
1 |
|
平方类欧几里得算法
设 $h(n,a,b,c)=\sum_{i=0}^n {\lfloor \frac {ai+b}{c} \rfloor}^2$,我们仍然需要在 $\log$ 时间范围内求出这个式子的值。
首先像普通类欧那样让 $a,b \gets a \bmod c,b \bmod c$。
考虑化一下,设 $a=pc+p’(0\le p’<c),b=qc+q’(0 \le q’ < c)$,则:
$$
\begin{aligned}
h(n,a,b,c)&=\sum_{i=0}^n {\lfloor \frac {ai+b}{c} \rfloor}^2 \\
&=\sum_{i=0}^n {(\lfloor \frac {p’i+q’}{c} \rfloor+pi+q)}^2 \\
&=\sum_{i=0}^n {\lfloor \frac {p’i+q’}{c} \rfloor}^2+\sum_{i=0}^n p^2i^2+\sum_{i=0}^n q^2+2\sum_{i=0}^n pqi+2p\sum_{i=0}^n i\lfloor \frac{p’i+q’}{c} \rfloor+2q\sum_{i=0}^n \lfloor \frac{p’i+q’}{c} \rfloor
\end{aligned}
$$
其中第五个项是等会要讲的带权类欧几里得算法,暂且设 $g(n,a,b,c)=\sum_{i=0}^n i\lfloor \frac {ai+b}{c} \rfloor$,则原式变为:
$$
h(n,a,b,c)=h(n,p’,q’,c)+2qf(n,p’,q’,c)+2pg(n,p’,q’,c)+p^2\frac {n(n+1)(2n+1)}{6}+q^2(n+1)+pqn(n+1)
$$
接下来我们只需要计算 $h(n,p’,q’,c)$ 的值,因为 $p’,q’<c$,我们可以继续推导。
$$
h(n,a,b,c)=\sum_{i=0}^n {\lfloor \frac {ai+b}{c} \rfloor}^2
$$
首先 $t^2=2 \times \frac {t(t+1)}{2}-t$,所以:
$$
h(n,a,b,c)=\sum_{i=0}^n (2\sum_{j=1}^{\lfloor \frac {ai+b}{c} \rfloor}j-\lfloor \frac {ai+b}{c} \rfloor)=2\sum_{i=0}^n \sum_{j=1}^{\lfloor \frac {ai+b}{c} \rfloor} j-f(n,a,b,c)
$$
后面可以直接计算,看前面的:
$$
\begin{aligned}
\sum_{i=0}^n \sum_{j=1}^{\lfloor \frac {ai+b}{c} \rfloor} j &= \sum_{j=0}^{m-1} (j+1)\sum_{i=0}^n {[j< \lfloor \frac {ai+b}{c} \rfloor]} \\
&= \sum_{j=0}^{m-1} (j+1) \sum_{i=0}^n [\lfloor \frac {cj+c-b-1}{a} \rfloor <i] \\
&= \sum_{j=0}^{m-1} (j+1)(n-\lfloor \frac {cj+c-b-1}{a} \rfloor) \\
&= nm+n \frac {m(m-1)}{2}-f(m-1,c,c-b-1,a)-g(m-1,c,c-b-1,a)
\end{aligned}
$$
带回原式,得:
$$
h(n,a,b,c)=nm(m+1)-2f(m-1,c,c-b-1,a)-2g(m-1,c,c-b-1,a)-f(n,a,b,c)
$$
带权类欧几里得算法
在 $\log$ 时间复杂度内求解 $g(n,a,b,c)=\sum_{i=0}^n i \lfloor \frac {ai+b}{c} \rfloor$。
先化掉 $a \ge c,b \ge c$ 的情况,设 $a=pc+p’,b=qc+q’(0 \le p’,q’<c)$,则:
$$
\sum_{i=0}^n i\lfloor \frac {ai+b}{c} \rfloor= \sum_{i=0}^n i(\lfloor \frac {p’i+q’}{c} \rfloor+pi+q)=\sum_{i=0}^n i \lfloor \frac {p’i+q’}{c} \rfloor+\sum_{i=0}^n pi^2+\sum_{i=0}^n qi
$$
后面两个和式可以 $O(1)$ 计算。
设 $m=\lfloor \frac {an+b}{c} \rfloor$,还是化一下式子:
$$
\begin{aligned}
\sum_{i=0}^n i \lfloor \frac {ai+b}{c} \rfloor &= \sum_{i=0}^n i\sum_{j=0}^{\lfloor \frac {ai+b}{c} \rfloor-1} 1 \\
&= \sum_{j=0}^{m-1} \sum_{i=0}^n i[j<\lfloor \frac {ai+b}{c} \rfloor]
\end{aligned}
$$
采用之前的方法,化掉艾佛森括号:
$$
\begin{aligned}
\sum_{j=0}^{m-1} \sum_{i=0}^n i[j<\lfloor \frac {ai+b}{c} \rfloor] &= \sum_{j=0}^{m-1} \sum_{i=0}^n i[\lfloor \frac {cj+c-b-1}{a} \rfloor<i] \\
t \gets \lfloor \frac {cj+c-b-1}{a} \rfloor \\
&= \sum_{j=0}^{m-1} \frac {(t+1+n)(n-t)}{2} \\
&= \frac 12(\sum_{j=0}^{m-1}(n^2+n)-\sum_{j=0}^{m-1} (t^2+t)) \\
&= \frac 12 ((n^2+n)m-\sum_{j=0}^{m-1} t^2-\sum_{j=0}^{m-1}t)
\end{aligned}
$$
因此,和式都可以递归进行计算,于是:
$$
g(n,a,b,c)=\frac 12(n(n+1)m-h(m-1,c,c-b-1,a)-f(m-1,c,c-b-1,a))
$$
其他事项
单个函数计算显然会超时,于是我们考虑用一个结构体存下 $n,a,b,c$ 对应的 $f,g,h$ 值,这样就可以在 $\log$ 时间内快速计算三个函数的值了,代码中的 $h$ 和 $g$ 函数交换了含义,读的时候要注意一下:
1 |
|
万能欧几里得算法
待补。