优雅的万能欧几里得

优雅的万能欧几里得

取自 CTT 2022 Day4 T3 (或许是2021?)

问题描述

考虑用以下方法描述一个万能欧几里得问题:

有一条端点为 \((0,0)\rightarrow (A,B)\) 的有向线段 \(OP\),我们认为其两端都是空的。

其中 \(A,B\) 是自然数, \(\gcd(A,B)=1\)。(当 \(g=\gcd(A,B)\ne 1\) 时,可以先求 \(\frac{A}{g},\frac{B}{g}\) 的结果,然后将其复制 \(g\) 次)。

万能欧几里得问题要维护这样的一个过程:

  1. 一开始我们有一个空字符串 \(s\)

  2. 考虑点从 \(O\) 移动到 \(P\) 的过程:

    1. \(x\) 坐标每经过一个整点,就向 \(s\) 中加入字符 \(\text{X}\)
    2. \(y\) 坐标每经过一个整点,就向 \(s\) 中加入字符 \(\text{Y}\)

注意在 \(O,P\) 处不加入字符。容易发现在 \(\gcd(A,B)=1\) 时,不会出现同时经过 \(x,y\) 上的整点。

下图是 \(P=(3,5)\) 时的例子,此时的字符串为 \(\text{YXYYXY}\)

line.png

在实际的应用中,我们用 \(\text{X,Y}\) 指代任何可拼接且满足结合律的操作(如矩阵)。

问题求解

用四元组 \((A,B,\text{X},\text{Y})\) 描述这样的一个万能欧几里得问题,则可以如下递归求解:

  1. \(B\ge A\),则每次在 \(x\) 增加之前, \(y\) 都会增加 \(\lfloor\frac{B}{A} \rfloor\) 个,可以转化为 \((A,B\mod A,\text{Y}\cdot \lfloor\frac{B}{A} \rfloor+\text{X},\text{Y})\)
  2. \(B<A\),则可以直接翻转坐标系,转化为求解 \((B,A,\text{Y},\text{X})\)。(而网上许多教程的翻转操作都需要处理复杂的边界条件)。

容易发现递归的问题同样是合法的万能欧几里得问题。

复杂度分析

\(l=\lfloor\frac{B}{A} \rfloor\),递归时需要处理 \(\text{Y}\cdot l\),这是一个快速幂操作,其复杂度为 \(\log l\)

\(B\mod A=B-A\cdot l\leq \frac{1}{l+1} B\),所以所有快速幂的复杂度总和为 \(\log A+\log B\)

区间查询

考虑万能欧几里得的过程,容易发现其中只有两种操作:

  1. 快速幂
  2. 直接拼接

如果我们用一个节点描述一个操作,就可以用二叉树的结构维护拼接操作。

对于快速幂,只需要对于节点进行可持久化。

而万能欧几里得所产生的二叉树至多只有 $\log $ 层,在这样的二叉树上查询的复杂度与线段树相同。

posted @ 2022-01-17 01:03  chasedeath  阅读(534)  评论(0编辑  收藏  举报