万能欧几里得算法学习笔记

万能欧几里得算法

基本描述

对于一条直线 px+rq,满足 p>0,q>0,r[0,q1],求解有关 px+rq,x 的一些函数。
考虑在坐标系上考虑这条直线,从 (0,0) 开始走。

定义当直线穿过一条形如 y=h(hZ) 的横线(下文会称其为横线)时进行一次 U 操作(往上走一格,对一些变量进行一定修改)。
定义当直线穿过一条形如 x=k(kZ) 的竖线(下文会称其为竖线)时进行一次 R 操作(往右走一格,对一些变量进行一定修改)。
特别的,规定直线遇到整点时先 U 后 R。

我们要求 U 和 R 操作有结合律。

算法流程

考虑将问题类似欧几里得算法的迭代过程,递归到子问题中。

solve(p,q,r,n,U,R) 表示处理 y=px+rq,x(0,n] 这一条线段,U,R 分别为遇到横竖线的操作序列。

  1. pq,我们尝试将问题递归到规模为 pmodq 的子问题。

    观察到 pq 时,每一个 R 操作前都会有至少 pq 个 U 操作,将其与 R 缩成一个操作,那么考虑新局面下 x 时的 U 操作个数:
    px+rqxpq=px+rqxp(pmodq)q=px+rxp+x(pmodq)q=(pmodq)x+rq

    递归到子问题 solve(pmodq,q,r,n,U,Up/qR) 即可。

  2. 否则,我们需要交换 p,q 的地位,进入第一部分的迭代。

    交换 p,q 地位类似于翻转坐标系,我们考虑第 a 个 R 前有 pa+rq 个 U。
    考虑第 b 个 U 前有多少个 R,设第 a 个 R 在第 b 个 U 前。

    b>pa+rq,b>pa+rqa<qbrp,aqbr1p

    b 个 U 前有 qbr1p 个 R。考虑还需解决的问题:

    1. r1 [0,p1]

      特殊处理操作序列没有 U 的情况,否则将原操作序列第一个 U 和其之前的 R 拿出来特殊处理。新直线变为 qx+(qr1modp)p

    2. 原问题操作序列结尾是 R,而地位反转后新问题结尾一定是原问题的 U 操作。

      仅剩若干个 R 操作未完成,递归结束后添上 nq×cntur1p(cntu=pn+rq) 个 R 操作即可。

若合并两个操作序列的复杂度为 O(c),那么万能欧几里得算法的复杂度为 O(clogmax(p,q))
复杂度证明类似欧几里得算法。

应用场景

对于这样的题目只要想清楚怎么维护操作序列的合并即可,迭代过程的代码都不需要修改!

ll div(ll a,ll b,ll c,ll d){return ((lll)a*b+c)/d;}
node solve(ll p,ll q,ll r,ll n,node U,node R){
    if(!n)return o;
    if(p>=q)return solve(p%q,q,r,n,U,power(U,p/q)+R);
    ll m=div(p,n,r,q);
    if(!m)return power(R,n);
    return (power(R,(q-r-1)/p)+U)+solve(q,p,(q-r-1)%p,m-1,R,U)+power(R,n-div(q,m,-r-1,p));
}

而能合并的操作序列也很广泛,仅要求是线性变换就可以了!

不愧其万能之称。

posted @   juju527  阅读(117)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示