【学习笔记】类欧几里得算法

Prologue

大家都知道,求 \(\gcd\) 的方法叫辗转相除法,又称欧几里得算法,它的思想大概就是把 \(f(a,b)\) 的值通过 \(f(b,a\bmod b)\) 来转移,从而达到 \(O(\log n)\) 的复杂度。

类欧几里得算法(类欧)也是运用了这个思想,但除此之外与 \(\gcd\) 并没有什么联系(

Intro

给定正整数 \(n,a,b,c(0\le a,b,c,n \le 10^{9})\),求 \(f(a,b,c,n) = \sum\limits_{i=0}^n\lfloor\frac{ai+b}{c}\rfloor\)

看见取整符号第一感觉当然是整除分块,然而似乎整除分块做不了。

首先考虑 \(a=0\) 的情况,此时显然有 \(f(a,b,c,n)=(n+1)\lfloor\frac{b}{c}\rfloor\)

然后考虑 \(a \ge c,b \ge c\) 的情况,把 \(a,b\) 都转移成小于 \(c\) 的数。

我们知道,对于正整数 \(x,y\),有 \(x = \lfloor\frac{x}{y}\rfloor y+(x \bmod y)\)。于是我们把原式展开可以得到:

\[\begin{aligned} f(a,b,c,n) = &\ \sum\limits_{i=0}^n\lfloor\frac{ai+b}{c}\rfloor\\ = &\ \sum\limits_{i=0}^n\lfloor\frac{(\lfloor\frac{a}{c}\rfloor c+(a \bmod c))i+(\lfloor\frac{b}{c}\rfloor c+(b \bmod c))}{c}\rfloor\\ = &\ \sum\limits_{i=0}^n\lfloor\frac{(a \bmod c)i+(b \bmod c)}{c}\rfloor+\lfloor\frac{a}{c}\rfloor i+\lfloor\frac{b}{c}\rfloor\\ = &\ f(a\bmod c,b\bmod c,c,n)+\frac{n(n+1)}{2}\lfloor\frac{a}{c}\rfloor +(n+1)\lfloor\frac{b}{c}\rfloor\\ \end{aligned} \]

剩下 \(a<c,b<c\) 时的情况。注意到原式里只有 \(i\) 一个变量,考虑变换一下计算 \(i\) 贡献的方式:

\[\begin{aligned} f(a,b,c,n) = &\ \sum\limits_{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} \]

然后这个不等式是不是看着很不爽,我们把它变换一下:

\[j < \lfloor\frac{ai+b}{c}\rfloor\\ j+1\le \frac{ai+b}{c}\\ cj+c\le ai+b\\ cj+c-b-1<ai\\ i > \lfloor\frac{cj+c-b-1}{a}\rfloor \]

再令 \(m=\lfloor\frac{an+b}{c}\rfloor\),于是原式就可以化为:

\[\begin{aligned} f(a,b,c,n) = &\ \sum_{j=0}^{m-1}\sum_{i=0}^n[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]\\ = &\ \sum_{j=0}^{m-1}(n- \lfloor\frac{cj+c-b-1}{a}\rfloor)\\ = &\ mn-f(c,c-b-1,a,m-1) \end{aligned} \]

此时我们发现 \(a,c\) 互换了位置,于是可以递归下去,按照辗转相除的思想进行处理。总结下来就是这样:

\[f(a,b,c,n)=\left\{ \begin{array}{lr} (n+1)\lfloor\frac{b}{c}\rfloor & a=0\\ f(a\bmod c,b\bmod c,c,n)+\frac{n(n+1)}{2}\lfloor\frac{a}{c}\rfloor +(n+1)\lfloor\frac{b}{c}\rfloor & a\ge c,b\ge c\\ mn-f(c,c-b-1,a,m-1) & \text{otherwise} \end{array} \right. \]

时间复杂度显然与 \(\gcd\) 相同,为 \(O(\log (a+c))\)

Extend

给定 \(n,a,b,c\),求:

\[g(a,b,c,n) = \sum_{i=0}^n\lfloor\frac{ai+b}{c}\rfloor^2\\h(a,b,c,n)=\sum_{i=0}^ni\lfloor\frac{ai+b}{c}\rfloor \]

\(g\) 的推导

\(a=0\) 时,显然有 \(g(a,b,c,n)=(n+1)\lfloor\frac b c\rfloor^2\)

\(a\ge c,b \ge c\) 时:

\[g(a,b,c,n)=g(a\bmod c,b\bmod c,c,n)+\frac{n(n+1)(2n+1)}{6}\lfloor\frac{a}{c}\rfloor^2+(n+1)\lfloor\frac b c\rfloor^2+\\ 2h(a\bmod c,b\bmod c,c,n)\lfloor\frac{a}{c}\rfloor+n(n+1)\lfloor\frac{a}{c}\rfloor\lfloor\frac b c\rfloor+2f(a\bmod c,b\bmod c,c,n)\lfloor\frac b c\rfloor \]

\(g\) 取模的推导过程

然后考虑 \(a<c,b<c\) 的情况。令 \(m=\lfloor\frac{an+b}{c}\rfloor,t=\lfloor\frac{cj+c-b-1}{a}\rfloor\)。于是有:

\[\begin{aligned} g(a,b,c,n) = &\ \sum_{i=0}^n\lfloor\frac{ai+b}c\rfloor^2\\ = &\ \sum_{i=0}^n\left(2(\sum_{j=0}^{\lfloor\frac{ai+b}c\rfloor}j)-{\lfloor\frac{ai+b}c\rfloor}\right)\\ = &\ \left(2\sum_{i=0}^n\sum_{j=0}^{\lfloor\frac{ai+b}c\rfloor}j\right)-f(a,b,c,n)\\ \end{aligned} \]

然后化简一下左边那玩意:

\[\begin{aligned} \sum_{i=0}^n\sum_{j=0}^{\lfloor\frac{ai+b}c\rfloor}j = &\ \sum_{i=0}^n\sum_{j=0}^{\lfloor\frac{ai+b}c\rfloor-1 }(j+1)\\ = &\ \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[i>t]\\ = &\ \sum_{j=0}^{m-1}(j+1)(n-t)\\ = &\ \sum_{j=0}^{m}jn-\sum_{j=0}^{m-1}(j+1)t\\ = &\ \frac{nm(m+1)}{2}-\sum_{j=0}^{m-1}j\lfloor\frac{cj+c-b-1}{a}\rfloor-\sum_{j=0}^{m-1}\lfloor\frac{cj+c-b-1}{a}\rfloor\\ = &\ \frac{nm(m+1)}2-h(c,c-b-1,a,m-1)-f(c,c-b-1,a,m-1) \end{aligned} \]

所以可以得到:

\[g(a,b,c,n)=nm(m+1)-2h(c,c-b-1,a,m-1)-2f(c,c-b-1,a,m-1)-f(a,b,c,n) \]

总结下来就是这样:

\[g(a,b,c,n)=\left\{ \begin{array}{lr} (n+1)\lfloor\frac b c\rfloor^2 & a=0\\ \\ g(a\bmod c,b\bmod c,c,n)+\frac{n(n+1)(2n+1)}{6}\lfloor\frac{a}{c}\rfloor^2+\\(n+1)\lfloor\frac b c\rfloor^2+ 2h(a\bmod c,b\bmod c,c,n)\lfloor\frac{a}{c}\rfloor+\\n(n+1)\lfloor\frac{a}{c}\rfloor\lfloor\frac b c\rfloor+2f(a\bmod c,b\bmod c,c,n)\lfloor\frac b c\rfloor & a\ge c,b\ge c\\ \\ nm(m+1)-2h(c,c-b-1,a,m-1)-\\2f(c,c-b-1,a,m-1)-f(a,b,c,n) & \text{otherwise} \end{array} \right. \]

\(h\) 的推导

\(a=0\) 时,\(h(a,b,c,n)=\frac{n(n+1)}{2}\lfloor\frac b c\rfloor\)

\(a\ge c,b\ge c\) 时:

\[h(a,b,c,n)=h(a\bmod c,b\bmod c,c,n)+\frac{n(n+1)(2n+1)}{6}\lfloor\frac a c\rfloor+\frac{n(n+1)}2\lfloor\frac b c\rfloor \]

\(h\) 取模的推导过程

然后令 \(m=\lfloor\frac{an+b}c\rfloor,t=\lfloor\frac{cj+c-b-1}a\rfloor\),继续推柿子:

\[\begin{aligned} h(a,b,c,n) = &\ \sum_{i=0}^ni\lfloor\frac{ai+b}{c}\rfloor\\ = &\ \sum_{i=0}^n\sum_{j=0}^{\lfloor\frac{ai+b}c\rfloor-1}i\\ = &\ \sum_{j=0}^{m-1}\sum_{i=0}^ni[j<\lfloor\frac{ai+b}{c}\rfloor]\\ = &\ \sum_{j=0}^{m-1}\sum_{i=0}^ni[i>t]\\ = &\ \sum_{j=0}^{m-1}\frac{(n-t)(n+t+1)}{2}\\ = &\ \frac 1 2\sum_{j=0}^{m-1}(n^2+n-t^2-t)\\ = &\ \frac{mn(n+1)}{2}-\sum_{j=0}^{m-1}\lfloor\frac{cj+c-b-1}a\rfloor^2-\sum_{j=0}^{m-1}\lfloor\frac{cj+c-b-1}a\rfloor\\ = &\ \frac{mn(n+1)}{2}-g(c,c-b-1,a,m-1)-f(c,c-b-1,a,m-1) \end{aligned} \]

总结下来就是这样:

\[h(a,b,c,n)=\left\{ \begin{array}{lr} \frac{n(n+1)}{2}\lfloor\frac b c\rfloor & a=0\\ h(a\bmod c,b\bmod c,c,n)+\frac{n(n+1)(2n+1)}{6}\lfloor\frac a c\rfloor+\frac{n(n+1)}2\lfloor\frac b c\rfloor & a\ge c,b\ge c\\ \frac{mn(n+1)}{2}-g(c,c-b-1,a,m-1)-f(c,c-b-1,a,m-1) & \text{otherwise} \end{array} \right. \]

Ex-extend

上面这三个柿子都是基于 \(a,b,c\) 均为非负整数的基础上的(否则不等式的推导有问题)。那么当 \(a,b,c\) 小于 \(0\) 时该怎么办?

  • \(a<0\)\(k=\lceil\frac{-a}{c}\rceil, \lfloor\frac{ai+b}{c}\rfloor\rightarrow\lfloor\frac{(ck+a)i+b}{c}\rfloor-ki\)
  • \(b<0\)\(k=\lceil\frac{-b}{c}\rceil,\lfloor\frac{ai+b}c\rfloor\rightarrow\lfloor\frac{ai+(ck+b)}{c}\rfloor-k\)
  • \(c<0\):不知道有没有更简单的做法,先放一个自己口胡的(

注意到有 \(\lfloor\frac{ai+b}{c}\rfloor=-\lceil\frac{ai+b}{-c}\rceil\),所以原式可以化一下:

\[\begin{aligned} f(a,b,c,n) = &\ -\sum_{i=0}^n\lceil\frac{ai+b}{-c}\rceil\\ = &\ -\left(\sum_{i=0}^n\lfloor\frac{ai+b}{-c}\rfloor+n+1-\sum_{i=0}^n[-c\mid(ai+b)]\right)\\ \end{aligned} \]

其中 \(\sum_{i=0}^n[-c\mid(ai+b)]\) 是可以在 \(\log\) 的时间内求出来的,于是原式就出来了(

恶心-extend

LibreOJ #138

给定 \(n,a,b,c,k_1,k_2\),求:

\[\sum_{x=0}^nx^{k_1}\left\lfloor\frac{ax+b}c\right\rfloor^{k_2}\bmod p \]

\(T=1000\)\(1\le n,a,c\le10^9\)\(0\le b\le 10^9\)\(0\le k_1+k_2\le10\)\(p=10^9+7\)

待填坑

Problems

  1. P5170 【模板】类欧几里得算法

\(\sum_{i=0}^n\lfloor\frac{ai+b}c\rfloor\)\(\sum_{i=0}^n\lfloor\frac{ai+b}c\rfloor^2\)\(\sum_{i=0}^ni\lfloor\frac{ai+b}c\rfloor\),对 \(998244353\) 取模。

这题显然就是刚才的 \(f,g,h\) 的计算。注意到 \(g,h\) 的计算中有很多的重复调用,因此我们可以将这三个函数同步计算。复杂度 \(O(\log(a+c))\)

  1. P5171 Earthquake

\(ax+by\le c\) 的非负整数解个数。

把原式变换一下:

\[ax+by\le c\\ by\le c-ax\\ y\le\lfloor\frac{c-ax}{b}\rfloor \]

所以对于每个 \(x\) 的可能取值,\(y\) 都有 \(\lfloor\frac{c-ax}{b}\rfloor+1\) 种取值(加 \(1\) 是因为 \(y\) 可以取 \(0\))。又注意到当 \(x>\lfloor\frac c a\rfloor\)\(c-ax<0\),所以解数的式子就出来了:

\[\sum_{x=0}^{\lfloor\frac c a\rfloor}(\lfloor\frac{c-ax}{b}\rfloor+1) \]

稍微推导一下:

\[\begin{aligned} \sum_{x=0}^{\lfloor\frac c a\rfloor}(\lfloor\frac{c-ax}{b}\rfloor+1) = &\ \sum_{x=0}^{\lfloor\frac c a\rfloor}\lfloor\frac{c-ax}{b}\rfloor+\lfloor\frac{c}{a}\rfloor+1\\ = &\ \sum_{x=0}^{\lfloor\frac c a\rfloor}(\lfloor\frac{(b-a)x+c}{b}\rfloor-x)+\lfloor\frac{c}{a}\rfloor+1\\ = &\ \sum_{x=0}^{\lfloor\frac c a\rfloor}\lfloor\frac{(b-a)x+c}{b}\rfloor-\frac{\lfloor\frac{c}{a}\rfloor(\lfloor\frac{c}{a}\rfloor+1)}{2}+\lfloor\frac{c}{a}\rfloor+1\\ \end{aligned} \]

前面显然可以用前面 \(f\) 函数来解决,如果 \(a>b\) 那么 \(\operatorname{swap}(a,b)\) 即可。

  1. P5172 Sum

\(\sum_{d=1}^n(-1)^{\lfloor d\sqrt r\rfloor}\)

首先注意到一个性质:

\[\begin{aligned} (-1)^x = &\ \begin{cases} 1 & x\equiv0\pmod2\\ -1 & x\equiv1\pmod2\\ \end{cases}\\ = &\ 1-2x+4\lfloor\frac x 2\rfloor \end{aligned} \]

所以原式可以化为:

\[\begin{aligned} \sum_{d=1}^n(-1)^{\lfloor d\sqrt r\rfloor} = &\ \sum_{d=1}^n(1-2\lfloor d\sqrt r\rfloor+4\lfloor\frac { d\sqrt r} 2\rfloor)\\ = &\ n-2\sum_{d=1}^n\lfloor d\sqrt r\rfloor+4\sum_{d=1}^n\lfloor\frac { d\sqrt r} 2\rfloor \end{aligned} \]

\(f(a,b,c,n)=\sum_{d=1}^n\lfloor\frac{a\sqrt r+b}{c}d\rfloor\),那么原式可以化为 \(n-2f(1,0,1,n)+4f(1,0,2,n)\)

\(x=\sqrt r\)\(k=\frac{ax+b}{c}\),那么 \(f(a,b,c,n)=\sum_{d=1}^n\lfloor kd\rfloor\)

然后利用类欧的思想推个柿子:

  • \(k\ge 1,\lfloor k\rfloor\not=0\)

\[\begin{aligned} \sum_{d=1}^n\lfloor kd\rfloor = &\ \sum_{d=1}^n\lfloor kd-\lfloor k \rfloor d+\lfloor k \rfloor d\rfloor\\ = &\ \sum_{d=1}^n\lfloor (\frac{ax+b}{c}-\lfloor k \rfloor )d\rfloor+\frac{n(n+1)}{2}\lfloor k \rfloor \\ = &\ \sum_{d=1}^n\lfloor \frac{ax+b-c\lfloor k \rfloor}{c}d\rfloor+\frac{n(n+1)}{2}\lfloor k \rfloor \\ = &\ f(a,b-c\lfloor k \rfloor,c,n)+\frac{n(n+1)}{2}\lfloor k \rfloor \end{aligned} \]

  • \(k<1,\lfloor k\rfloor=0\)

\[\begin{aligned} \sum_{d=1}^n\lfloor kd\rfloor = &\ \sum_{d=1}^n\sum_{i=1}^{\lfloor kn\rfloor}[i< kd]\\ = &\ \sum_{i=1}^{\lfloor kn\rfloor}\sum_{d=1}^n[d>\lfloor\frac i k\rfloor]\\ = &\ \sum_{i=1}^{\lfloor kn\rfloor}(n-\lfloor\frac i k\rfloor)\\ = &\ n\cdot\lfloor kn\rfloor-\sum_{i=1}^{\lfloor kn\rfloor}\lfloor\frac c {ax+b}i\rfloor\\ = &\ n\cdot\lfloor kn\rfloor-\sum_{i=1}^{\lfloor kn\rfloor}\lfloor\frac {c(ax-b)} {(ax+b)(ax-b)}i\rfloor\\ = &\ n\cdot\lfloor kn\rfloor-\sum_{i=1}^{\lfloor kn\rfloor}\lfloor\frac {acx-bc} {a^2r-b^2}i\rfloor\\ = &\ n\cdot\lfloor kn\rfloor-f(ac,-bc,a^2r-b^2,\lfloor kn\rfloor) \end{aligned} \]

由于 \(x\) 是无理数,最后一步要做一遍有理化。分子分母在计算过程中要约分,否则会炸掉。

  1. P5179 Fraction

求一个分子分母最小的最简分数 \(\frac p q\),满足 \(\frac a b<\frac pq<\frac cd\)

分类讨论一下。

  • \(\lfloor\frac ab\rfloor+1\le\lceil\frac cd\rceil-1\):此时 \(\frac ab\)\(\frac cd\) 中间有一个整数,取 \(p=\lfloor\frac ab\rfloor+1\)\(q=1\) 即可。
  • \(a=0\):此时 \(\frac ab=0\),那么只需满足 \(\frac cd\) 的条件,取 \(p=1\)\(q=\lfloor\frac dc\rfloor+1\) 即可。
  • \(a<b\):可以同时取倒数处理,递归求解 \(\frac dc<\frac qp<\frac ba\) 即可。
  • \(a\ge b\):令 \(k=\lfloor\frac ab\rfloor\),那么可以把原式全都减去 \(k\),递归求解 \(\frac {a-kb}b<\frac{p-kq}q<\frac{c-kd}d\) 即可。

注意到前两种情况其实都是边界条件,而后两种情况其实就是一种辗转相除法,故也属于类欧几里得算法。

  1. P4433 [COCI2009-2010#1] ALADIN

解决题目的关键显然在于维护 \(\sum_{i=1}^ni\times A\bmod B\) 这个式子。

稍微转化一下:

\[\begin{aligned} \sum_{i=1}^ni\times A\bmod B = &\ \sum_{i=1}^n\left(i\times A-\lfloor\frac{i\times A}B\rfloor B\right)\\ = &\ A\sum_{i=1}^ni-B\sum_{i=1}^n\lfloor\frac{i\times A}B\rfloor\\ = &\ \frac{n(n+1)}2A-B\cdot f(A,0,B,n) \end{aligned} \]

于是可以 \(\log\) 的时间内求出值。然后把每个操作的 \(l,r\) 离散化一下,线段树维护即可。

Epilogue

水。

能水五道黑题。

发财。

posted @ 2022-01-13 22:22  Sya_Resory  阅读(43)  评论(0编辑  收藏  举报