万能欧几里德算法

算法简介

有半群 \((G, \cdot)\)。给出 \(a, b, c, n, U, R\),满足 \(a, b, c, n \in N\)\(U, R \in G\)\(\max\{a, c\} < b\),试求

\[f(a, b, c, n, U, R) = \prod_{x = 1}^n (U^{\lfloor \frac{ax + c}{b} \rfloor - \lfloor \frac{a(x - 1) + c}{b} \rfloor} \cdot R) \]

通俗来讲,\(f(a, b, c, n, U, R)\) 表示有 \(n\)\(R\)、其中第 \(x\)\(R\) 前面共有 \(\lfloor \frac{ax + c}{b} \rfloor\)\(U\) 时所有元素的乘积。

下文记 \(m = \lfloor \frac{an + c}{b} \rfloor\),表示 \(f(a, b, c, n, U, R)\)\(U\) 的个数。

万能欧几里德算法能够通过 \(O(\log b)\) 次乘法运算计算出 \(f(a, b, c, n, U, R)\),它包含下述两种操作。

操作一:交换 \(a, b\)

考察第 \(y\)\(U\),在它前面的 \(R\) 的个数即为 \(\lfloor \frac{ax + c}{b} \rfloor < y\)\(x\) 的最大非负整数解:

\[\begin{aligned} \lfloor \frac{ax + c}{b} \rfloor &< y \\ \frac{ax + c}{b} &< y \\ x &< \frac{by - c}{a} \\ x &\le \lfloor \frac{by - c - 1}{a} \rfloor \end{aligned} \]

此时有 \(-c - 1 < 0\),不满足递归条件,考虑把第一个 \(U\) 及之前的 \(R\) 单独拿出来,这样新的第 \(i\)\(U\) 之前的 \(R\) 的个数为:

\[\begin{aligned} &\lfloor \frac{b(i + 1) - c - 1}{a} \rfloor - \lfloor \frac{b - c - 1}{a} \rfloor \\ = &\lfloor \frac{bi + b - c - 1}{a} \rfloor - \frac{b - c - 1 - (b - c - 1) \bmod a}{a} \\ = &\lfloor \frac{bi + (b - c - 1) \bmod a}{a} \rfloor \end{aligned} \]

综上,我们有 \(f(a, b, c, n, U, R) = R^{\lfloor \frac{b - c - 1}{a} \rfloor} \cdot U \cdot f(b, a, (b - c - 1) \bmod a, m - 1, R, U) \cdot R^{n - \lfloor \frac{bm - c - 1}{a} \rfloor}\)

操作二:将 \(a\) 变为 \(a \bmod b\)

考察第 \(x\)\(R\),在它前面有 \(\lfloor \frac{ax + c}{b} \rfloor = \lfloor \frac{(a \bmod b)x + c}{b} \rfloor + \lfloor \frac{a}{b} \rfloor\)\(U\)

因此我们有 \(f(a, b, c, n, U, R) = f(a \bmod b, b, c, n, U, U^{\lfloor \frac{a}{b} \rfloor} \cdot R)\)

万能欧几里德算法

考虑交替进行操作一、二。

\[f(a, b, c, n, U, R) = \left\{ \begin{aligned} &R^{\lfloor \frac{b - c - 1}{a} \rfloor} \cdot U \cdot f(b \bmod a, a, (b - c - 1) \bmod a, m - 1, R, R^{\lfloor \frac{b}{a} \rfloor} \cdot U) \cdot R^{n - \lfloor \frac{bm - c - 1}{a} \rfloor} & m > 0 \\ &R^n & m = 0 \end{aligned} \right. \]

容易发现该算法的递归次数与计算 \(\gcd(a, b)\) 时使用的欧几里德算法完全相同,为 \(O(\log b)\) 次。

考虑使用快速幂计算算法中涉及的取幂运算。

计算 \(R^{\lfloor \frac{b - c - 1}{a} \rfloor}\)\(R^{\lfloor \frac{b}{a} \rfloor}\) 显然需要 \(O(\log \frac{b}{a})\) 次乘法运算。

考虑分析计算 \(R^{n - \lfloor \frac{bm - c - 1}{a} \rfloor}\) 所需的乘法次数:

\[\begin{aligned} &O(n - \frac{bm - c - 1}{a}) \\ = &O(n - \frac{an + c - c - 1}{a}) \\ = &O(1) \end{aligned} \]

因此计算 \(R^{n - \lfloor \frac{bm - c - 1}{a} \rfloor}\) 只需要 \(O(1)\) 次乘法运算。

综上,每一层的乘法次数为 \(O(\log \frac{b}{a}) = O(\log b - \log a)\) 次。

递归到下一层时 \(a, b\) 交换,乘法次数为 \(O(\log a - \log(b \bmod a))\) 次。

发现上一层的 \(O(-\log a)\) 可以抵消掉下一层的 \(O(\log a)\),因此万能欧几里德算法总乘法次数为 \(O(\log b)\) 次。

代码实现

template <typename T>
T qpow(T x, ll y) {
  T ret;
  for (; y; y >>= 1, x = x * x)
    if (y & 1) ret = ret * x;
  return ret;
}
template <typename T>
T solve(ll a, ll b, ll c, ll n, T U, T R) {
  ll m = (a * n + c) / b;
  if (!m) return qpow(R, n);
  return qpow(R, (b - c - 1) / a) * U *
         solve(b % a, a, (b - c - 1) % a, m - 1, R, qpow(R, b / a) * U) *
         qpow(R, n - (b * m - c - 1) / a);
}

例题

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

我们只需要设计合适的半群元素与乘法运算即可。

半群中的每一个元素代表一个由 \(U, R\) 组成的序列,维护五个信息:

  1. \(U\) 的个数

  2. \(R\) 的个数

  3. 每一个 \(R\) 「前面的 \(U\) 的个数」之和

  4. 每一个 \(R\) 「前面的 \(U\) 的个数」的平方和

  5. 每一个 \(R\) 「前面的 \(U\) 的个数」乘以「前面的 \(R\) 的个数加一」之和

容易发现维护上述五个信息即可支持合并序列,即乘法运算。

时间复杂度 \(O(T \log \max\{a, b, c\})\)

提交记录

ARC166E Fizz Buzz Difference

\(f(l, r) = \sum_{i = l}^r [a \mid i] - [b \mid i]\)

先考虑求出 \(\max\{r - l \mid f(l, r) = n\}\)

不难发现 \(\lim\limits_{r \to +\infty} f(l, r) = +\infty\)\(|f(l, r) - f(l, r + 1)| \le 1\)。进而 \(\forall s \in N, \max\{r - l \mid f(l, r) = s\} < \max\{r - l \mid f(l, r) = s + 1\}\),因此转化为求解 \(\max\{r - l \mid f(l, r) \le n\}\)

观察到最长的满足 \(f(l, r) \le n\) 的区间 \([l, r]\) 一定满足 \(a \mid l - 1 \land a \mid r + 1\)。这是因为如果 \(a \nmid l - 1\) 那么 \(f(l - 1, r) \le n\),如果 \(a \nmid r + 1\) 那么 \(f(l, r + 1) \le n\),都能导出矛盾。

因此又转化为求解 \(\max\{r - l \mid f(la + 1, ra - 1) \le n \}\)。我们会让 \(b\) 的倍数的出现位置尽可能多,也即让第一个 \(b\) 的倍数出现位置尽可能靠前。具体地,我们一定能使 \(b \mid la + \gcd(a, b)\)。于是直接列不等式就能解出区间长度的最大值。

求出了区间长度的最大值之后,我们还需要求出最小的 \(l\) 使得 \([la + 1, ra - 1]\)\(b\) 的倍数个数取到理论最大值。这相当于找到 \(ax \bmod b \ge lim\) 的最小的非负整数 \(x\)

不妨假设 \(\gcd(a, b) = 1\),如果不是可以让 \(a, b, lim\) 同时除以 \(\gcd(a, b)\) 而答案不变。先用扩展欧几里德算法解出 \(ax + by = 1\) 的一组解 \((x_0, y_0)\)。枚举 \(i = ax \bmod b\),所求即:

\[\begin{aligned} &\min_{i = lim}^{b - 1} ix_0 \bmod b \\ = &\min_{i = lim}^{b - 1} ix_0 - b \lfloor \frac{ix_0}{b} \rfloor \\ = &(lim - 1)x_0 + \min_{i = 1}^{b - lim} ix_0 - b\lfloor \frac{ix_0 + (lim - 1)x_0}{b} \rfloor \end{aligned} \]

下式右项可以使用万能欧几里德算法求解。我们把 \(U\) 看作 \(-b\),把 \(R\) 看作 \(+x_0\),右项即求所有 \(R\) 处前缀和的最小值。容易设计出半群元素和乘法运算。

时间复杂度 \(O(T \log b)\)

提交记录

CF500G New Year Running

求出路径交后,从一端开始给上面的每个点从 \(0\) 开始依次编号。在此基础上画出两人的 \(s - t\) 图像:如果 \((x, y)\) 在某人的图像中则表示他时刻 \(x\) 时位于路径交上编号为 \(y\) 的节点。原问题转化为求出两人 \((x, y)\) 图像的横坐标最小的交点。

不难发现,每个人的 \(s - t\) 图像都由两部分组成:周期性重复的若干条斜率为 \(1\) 的线段,和周期性重复的若干条斜率为 \(-1\) 的线段。考虑把每个人 \(s - t\) 图像的两部分分开求交点。

如果求交点的两组周期性重复的线段斜率相同,那么有交等同于重合。容易使用扩展欧几里德算法 \(O(\log n)\) 求解。

否则,由于重复间隔(即对应人的路径长度的两倍)长度为偶数,排除掉不可能交在整点的情况后,剩下的情况只要横坐标范围有交就一定交在整点。记第一个人重复间隔为 \(a\),第二个人重复间隔为 \(b\)。第一个人的第 \(x\) 条线段和第二个人的第 \(y\) 条线段横坐标有交(\(x, y\)\(0\) 开始编号),限制形如 \(l \le ax - by \le r\);如果最后的横坐标最小的交点是这两条线段的交点,那么答案形如 \(\frac{c + ax + by}{2}\)。因此,我们需要求出 \(\min\{ax + by \mid l \le ax - by \le r\}\)

不妨假设 \(\gcd(a, b) = 1\),如果不是则一定可以转化。先用扩展欧几里德算法求出 \(ax - by = 1\) 的一组解 \((x_0, y_0)\),枚举 \(i = ax - by\),所求转化为:

\[\min_{i = l}^r a(ix_0 - b \lfloor \min\{\frac{ix_0}{b}, \frac{iy_0}{a}\} \rfloor) + b(iy_0 - a \lfloor \min\{\frac{ix_0}{b}, \frac{iy_0}{a}\} \rfloor) \]

\(l \le 0 \le r\) 的情况一定有 \((0, 0)\) 作为最优解,\(r < 0\) 的情况可以全部乘以 \(-1\) 转化为 \(l > 0\)。当 \(l > 0\) 时,记 \(\frac{p}{q} = \min\{\frac{x_0}{b}, \frac{y_0}{a}\}\),上式转化为:

\[\begin{aligned} &\min_{i = l}^r a(ix_0 - b \lfloor \frac{ip}{q} \rfloor) + b(iy_0 - a \lfloor \frac{ip}{q} \rfloor) \\ = &\min_{i = l}^r (ax_0 + by_0)i - 2ab \lfloor \frac{ip}{q} \rfloor \\ = &(l - 1)(ax_0 + by_0)i + \min_{i = 1}^{r - l + 1} (ax_0 + by_0)i - 2ab \lfloor \frac{ip + (l - 1)p}{q} \rfloor \end{aligned} \]

类似上文的 ARC166E,最下式右项可以通过万能欧几里德算法求解。

时间复杂度 \(O(T \log n)\)

提交记录

CF868G El Toll Caves

不难猜到最优策略一定是第 \(i\) 天检查编号为 \(ik \bmod n, (ik + 1) \bmod n, (ik + 2) \bmod n, \dots, (ik + k - 1) \bmod n\)\(k\) 个洞穴(洞穴编号从 \(0\) 开始)。这是因为宝藏在任何一个洞穴里的可能性都相等,我们希望每个洞穴被检查的次数尽可能平均。

\(f_i\) 表示宝藏在洞穴 \(i\) 时的期望天数。稍加推导不难发现:

\[f_i = \left\{ \begin{aligned} &f_{i - k} + 1 & i \ge k \\ &\frac{1}{2} f_{i - k + n} + 1 & i < k \end{aligned} \right. \]

容易发现这些转移连成了 \(\gcd(n, k)\) 条长为 \(\frac{n}{\gcd(n, k)}\) 环,每条环上的 \(f\) 完全相同,于是只需要考虑 \(\gcd(n, k) = 1\) 的情况即可。

此时,令 \(f_0\) 为主元,从 \(0\) 开始不断 \(+ k\),在环上走一圈即可 \(O(n)\) 解出 \(f_0\),进而求得 \(\frac{1}{n}\sum_{i = 0}^{n - 1} f_i\)

考虑使用万能欧几里德算法加速「走一圈」的过程。每走一步,如果跨过了一个周期就先 \(\times \frac{1}{2}\)\(+1\),否则直接 \(+1\)。容易发现走第 \(x\) 步之前共进行了 \(\lfloor \frac{kx}{n} \rfloor\)\(\times \frac{1}{2}\),这对应着第 \(x\)\(R\) 之前有 \(\lfloor \frac{kx}{n} \rfloor\)\(U\)

我们把 \(\times \frac{1}{2}\) 看作 \(U\)\(+1\) 看作 \(R\),对于每个半群元素维护:

  1. \((k, b)\) 表示 \(x\) 经过该元素对应的 \(U, R\) 操作序列后变为了 \(kx + b\)

  2. \((s_k, s_b)\) 表示 \(x\) 经过该元素对应的 \(U, R\) 操作序列在进行完每个 \(R\) 操作后的和为 \(s_k x + s_b\)

容易设计乘法运算,由于 \((k, b)\) 本质是矩阵,因此不难验证其满足结合律。

时间复杂度 \(O(T \log n)\)

提交记录

posted @ 2023-10-20 13:32  JCY_std  阅读(106)  评论(0编辑  收藏  举报