浅谈类欧几里得算法

一只书虫仔

2020-05-27 10:43:32

Personal

类欧入门手册。 ### Background 类欧几里得算法主要解决直线下整点个数问题,像这样: > 给定一个函数 $f(x)=\frac{ax+b}{c}$,求当 $x\in [0,n]$ 且 $x \in \mathbf Z$ 时,$f(x)$ 下的整点个数之和是多少。 不难发现可以转化为一个求和的式子: $$\sum\limits_{i=0}^n \left\lfloor\frac{ai+b}{c}\right\rfloor$$ 我们今天就来解决这个问题。 ### Lemma 1 注:这一部分里的转换名称是我自己起的。 **求和转换** 为将一个数转换为若干个 $1$ 加起来的形式,如下所述: $$p=\sum\limits_{i=1}^p 1$$ ### Lemma 2 注:这一部分里的转换名称不是我自己起的。 **限制转换** 为当有两个求和第二个求和被第一个求和约束时,交换两个约束取消第二个求和被第一个求和的约束条件时,需要加上一个条件不等式作为第二个求和的约束,如下所述: $$\sum\limits_{i=1}^n \sum\limits_{j=1}^i p(i,j)=\sum\limits_{j=1}^n \sum\limits_{i=1}^n p(i,j)[j \le i]$$ ### Sample 1 >给定 $n,a,b,c$,求: > >$$\sum\limits_{i=0}^n \left\lfloor\frac{ai+b}{c}\right\rfloor$$ (试题链接 $\to $ [Link](https://www.luogu.com.cn/problem/P5170) 的第一部分) Lamma 1 & 2 看起来比较基础,但在类欧式子的推导中有很重要的作用。 我们将 **求和转换** 和 **限制转换** 一口气使用在这个式子上: $$\begin{aligned}\sum\limits_{i=0}^n \left\lfloor\frac{ai+b}{c}\right\rfloor&=\sum\limits_{i=0}^n \sum\limits_{j=0}^{\left\lfloor\frac{ai+b}{c}\right\rfloor-1}1\\&=\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\sum\limits_{i=0}^n 1\left[j<\left\lfloor\frac{ai+b}{c}\right\rfloor\right]\end{aligned}$$ 然后我们化简一下条件式里的不等式: $$\begin{aligned}j<\left\lfloor\frac{ai+b}{c}\right\rfloor&\to j+1 \le \left\lfloor\frac{ai+b}{c}\right\rfloor\\&\to j+1 \le \frac{ai+b}{c}\\&\to jc+c \le ai+b\\&\to jc+c-b-1 <ai\\&\to i>\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor\end{aligned}$$ 我们将其化简为 $i>p$ 的形式是便于将其进行像下面这样的化简: $$\sum\limits_{i=0}^n 1[i>p]=\sum\limits_{i=p+1}^n 1$$ 所以将上面那个式子代入: $$\begin{aligned}\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\sum\limits_{i=0}^n 1\left[j<\left\lfloor\frac{ai+b}{c}\right\rfloor\right]&=\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\sum\limits_{i=0}^n 1\left[i>\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor\right]\\&=\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\sum\limits_{i=\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor+1}^n1\end{aligned}$$ 然后我们把 **求和转换** 反过来用代入:即: $$\begin{aligned}\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\sum\limits_{i=\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor+1}^n1&=\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}n-\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor\\&=\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}n-\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor\\&=n\left\lfloor\frac{an+b}{c}\right\rfloor-\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor\end{aligned}$$ 好,我们化简完了,因为这个式子可以递归,后面这个式子跟我们要化简的式子模式是一样的,并且这个是优于暴力的,复杂度大概 $\mathcal O(\log n)$。 ### Summary 1 经过上面的推导,不难发现,类欧算法即为下面四个部分: - 求和转化 - 限制转化 - 将限制转化得到的不等式转化为 $i$ 与某个式子的大小关系 - 代入后进一步推导成递归的模式 是不是没有想象中的那么难? ### Practice 1 - [[BJOI 2012] 算不出的等式](https://www.luogu.com.cn/problem/P4132) 板题 - [loj 6245 红太阳](https://loj.ac/problem/6245) 将题目化为: $$\sum\limits_{i=0}^n\left\lfloor\frac{ai}{c}\right\rfloor$$ 后也是个板题。 ### Lemma 3 $$n^2=2\sum\limits_{i=1}^ni-n$$ 简证: $$\begin{aligned}2\sum\limits_{i=1}^ni-n&=2\dfrac{n(n+1)}{2}-n\\&=n(n+1)-n\\&=n^2\end{aligned}$$ ### Sample 2 > 给定 $n,a,b,c$,求: > > $$\sum\limits_{i=0}^n i\left\lfloor\frac{ai+b}{c}\right\rfloor$$ > $$\sum\limits_{i=0}^n \left\lfloor\frac{ai+b}{c}\right\rfloor^2$$ (试题链接 $\to$ [Link](https://www.luogu.com.cn/problem/P5170) 的二、三部分) 那么我们按照 Summary 1 总结的步骤开始吧! $$\begin{aligned}\sum\limits_{i=0}^n i\left\lfloor\frac{ai+b}{c}\right\rfloor&=\sum\limits_{i=0}^n \sum\limits_{j=0}^{\left\lfloor\frac{ai+b}{c}\right\rfloor-1}i\\&=\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\sum\limits_{i=0}^ni\left[j<\left\lfloor\frac{ai+b}{c}\right\rfloor\right]\end{aligned}$$ 化简不等式: $$\begin{aligned}j<\left\lfloor\frac{ai+b}{c}\right\rfloor&\to j+1 \le \frac{ai+b}{c}\\&\to jc+c \le ai+b\\&\to jc+c-b-1<ai\\&\to i>\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor\end{aligned}$$ 代入: $$\begin{aligned}\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\sum\limits_{i=0}^ni\left[j<\left\lfloor\frac{ai+b}{c}\right\rfloor\right]&=\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\sum\limits_{i=0}^ni\left[i>\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor\right]\\&=\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\sum\limits_{i=\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor+1}^n i\\&= \sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\left(\sum\limits_{i=1}^ni-\sum\limits_{i=1}^{\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor}i\right)\end{aligned}$$ 代入等差数列求和公式: $$\begin{aligned}\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\left(\sum\limits_{i=1}^ni-\sum\limits_{i=1}^{\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor}i\right)&=\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\left(\dfrac{n(n+1)}{2}-\dfrac{\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor\left(\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor\right)}{2}\right)\\&=\dfrac{1}{2}\left(\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}n(n+1)-\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor^2-\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor\right)\\&=\dfrac{1}{2}\left(\left\lfloor\frac{an+b}{c}\right\rfloor n(n+1)-\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor^2-\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor\right)\end{aligned}$$ 不难发现,最后一个式子里两个求和式子分别为 Sample 2 的第二个式子和 Sample 1 的式子。 接下来化简第二个式子,代入 Lemma 3: $$\begin{aligned}\sum\limits_{i=0}^n \left\lfloor\frac{ai+b}{c}\right\rfloor^2&=\sum\limits_{i=0}^n\left(2\sum\limits_{j=1}^{\left\lfloor\frac{ai+b}{c}\right\rfloor}j-\left\lfloor\frac{ai+b}{c}\right\rfloor\right)\\&=2\sum\limits_{i=0}^n\sum\limits_{j=1}^{\left\lfloor\frac{ai+b}{c}\right\rfloor}j-\sum\limits_{i=0}^n\left\lfloor\frac{ai+b}{c}\right\rfloor\end{aligned}$$ 减号后面的就是 Sample 1,我们接着化简减号前面的,并且再次代入两个转换: $$\begin{aligned}2\sum\limits_{i=0}^n\sum\limits_{j=1}^{\left\lfloor\frac{ai+b}{c}\right\rfloor}j&=2\sum\limits_{i=0}^n \sum\limits_{j=0}^{\left\lfloor\frac{ai+b}{c}\right\rfloor-1}(j+1)\\&=2\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\sum\limits_{i=0}^n(j+1)\left[j<\left\lfloor\frac{ai+b}{c}\right\rfloor\right]\end{aligned}$$ 化简不等式: $$\begin{aligned}j<\left\lfloor\frac{ai+b}{c}\right\rfloor&\to j+1 \le \frac{ai+b}{c}\\&\to jc+c \le ai+b\\&\to jc+c-b-1<ai\\&\to i>\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor\end{aligned}$$ 代入: $$\begin{aligned}2\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\sum\limits_{i=0}^n(j+1)\left[j<\left\lfloor\frac{ai+b}{c}\right\rfloor\right]&=2\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\sum\limits_{i=0}^n(j+1)\left[i>\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor\right]\\&=2\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\sum\limits_{i=\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor+1}^n(j+1)\\&=2\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}(j+1)\left(n-\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor\right)\\&=2\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}n(j+1)-2\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor(j+1)\\&=n\left\lfloor\frac{an+b}{c}\right\rfloor\left(\left\lfloor\frac{an+b}{c}\right\rfloor+1\right)-2\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}j\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor j-2\sum\limits_{j=0}^{\left\lfloor\frac{an+b}{c}\right\rfloor-1}\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor\end{aligned}$$ 这个部分包括了 Sample 2 的第一个式子和 Sample 1,当我们要求 Sample 2 的这两个式子的时候,可以考虑和 Sample 1 一块递归,总体时间复杂度依然是 $\mathcal O(\log n)$ 的。 ### Summary 2 第一个式子仍然跟 Sample 1 差不多,只不过最后一步用上了等差数列求和。 第二个式子需要先用 Lemma 3 进行一步化简再进行 Sample 1 的步骤。 ### Practice 2 - dWoi R2 D,等比赛结束后将会公布这题。 ### Summary End 本文只是类欧几里得算法的简介,或者入门手册,只讲解类欧几里得算法最基础的思路: - 两个转换 - 不等式化简 - 代入递推 经过不同的组合就会产生不同的题目。 ### Practice End 比较综合的两道题目,笔者并不是很会这两道题的所有步骤,因此只会把关键步骤写出来。 - [Codeforces 1182F Maxinum Sine](https://www.luogu.com.cn/problem/CF1182F) 将题目要求的东西转化为 $|2px \bmod 2q-q|$ 的最小值之后,进行二分,二分的 check 需要类欧,最后要用 exgcd 解,比较综合的题。 - [Codeforces 1098E Fedya the Potter](https://www.luogu.com.cn/problem/CF1098E) 运用双指针框定区间,然后二分,仍然是 check 函数里需要运用类欧。 ### Reference 1. [OI-Wiki 类欧几里得算法](https://oi-wiki.org/math/euclidean/)。 2. [AThousandMoon CF1182F 的题解](https://www.luogu.com.cn/blog/WDLGZH2017/solution-cf1182f)。