浅谈关于欧几里得的一系列算法

浅谈关于欧几里得的一系列算法

--------- 这里有个叫分界线的家伙说,本章的所有讨论均在整数的范围中,所有除法都为带余除法o----------------

朴素欧几里得算法

又名辗转相除法,代码实现如下:

int gcd(int a, int b) // a >= b 
{  
      if(b == 0)    return a;  
      return gcd(b, a % b)  
}

想一想为什么可以这样计算?

我们设

\(a=k_1m, \ b=k_2m \ ,gcd(a,b)=m,\ gcd(k_1,k_2)=1\)

很容易发现,当我们进行加减运算的时候,他们的和或者差一定是 \(m\) 的倍数,也就是说最大公约数不改变

既然这样,那么当 \(a\ mod\ b=0\) 的时候可以发现此时的 \(b\) 一定就是最大公约数 \(m\)

而我们为了造出这个特殊情况,我们可以像代码中展示的那样不停的迭代,由于我们始终保证了 \(a>b\) ,所以我们最后一定能得到我们想要的情况,从而得到 \(gcd\)

扩展欧几里得算法

这个算法的用处是用来解形如 \(ax + by = c\) 的不定方程

首先,如果你进行过一点思考的话就为发现必须满足条件 \(c \mid \ gcd(a,b)\) 原方程才有整数解

因此,我们可以把原式变成一个更容易讨论的形式

\(ax+by=gcd(a,b)\ \ (a>=b)\)

由于上面的思考,不难发现

\(\because gcd(a,b)=gcd(b,a\ mod\ b)\)

同上,我们依然讨论一下它的特殊情况,当 \(b=0\) 时,也就是 \(ax + by=a\) 时,显然 \(x=1,\ y=0\)

那么我们要做的就是通过这个临界情况,反推出原方程的一组解

$\therefore\ $ 我们假设

\(ax_1+by_1=gcd(a,b)\)

\(bx_2+(a\ mod\ b)y_2=gcd(b,a\ mod\ b)\)

然后对这个形式做一些变形

\(\Rightarrow\ ax_1+by_1=bx_2+(a\ mod\ b)y_2\)

\(\Rightarrow\ ax_1+by_1=bx_2+(a-\frac{a}{b}b)y_2\)

\(\Rightarrow\ ax_1+by_1=b(x_2-(\frac{a}{b})y_2)+ay_2\)

又由于恒等定理可得

\(x_1=y_2,\ y_1=x_2-(\frac{a}{b})y_2\)

这样,我们就可以通过 \(x_2,\ y_2\) ,推断出 \(x_1,\ y_1\)

同样的道理,我们也就这样迭代下去,就可以得出那组特殊的解了

由于它的方法和朴素欧几里得算法有莫大的关联,所以我们可以在原来的代码上加上一些神秘的东西,变成扩展欧几里得算法

int exgcd(int aaa, int bbb, int &x, int &y)  
{  
    if(bbb == 0)  
    {  
        x = 1;  
        y = 0;  
        return aaa;  
    }  
    g = exgcd(bbb, aaa % bbb);  
    int temp = x; x = y; y = temp - aaa / bbb * y;  
    return g;  
}

类欧几里得算法

这个算法其实可以衍生出好几种,接下来我们所讲解的是最基础,也是最经典的那一种

\(f(a,b,c,n)=\sum_{i=0}^n\lfloor\frac{ai+b}{c}\rfloor\)

我们要求的这个函数其实可以换个角度来观察

\(f(a,b,c,n)=\sum_{i=0}^n\lfloor\frac{a}{c}i+\frac{b}{c}\rfloor\)

其实这个函数的几何意义是一次函数下 \(x\in [0,n]\) 整点的个数(包含直线上的点,但是不包含 \(y=0\) 的点)

所以我们就可以在这个思想上在进行一些变化

\(m=\lfloor\frac{an+b}{c}\rfloor\)

\(f(a,b,c,n)=\sum_{i=0}^n\ \sum_{j=1}^m\ [\frac{ai+b}{c}>=j]\)

\(f(a,b,c,n)=\sum_{i=0}^n\ \sum_{j=0}^{m-1}\ [\frac{ai+b}{c}>=j+1]\)

\(f(a,b,c,n)=\sum_{i=0}^n\ \sum_{j=0}^{m-1}\ [ai>=cj+c-b]\)

\(f(a,b,c,n)=\sum_{i=0}^n\ \sum_{j=0}^{m-1}\ [ai>cj+c-b-1]\)

\(f(a,b,c,n)=\sum_{i=0}^n\ \sum_{j=0}^{m-1}\ [i>=(\frac caj+\frac{c-b-1}a)]\)

\(f(a,b,c,n)=\sum_{j=0}^{m-1}\ [n-(\frac caj+\frac{c-b-1}a)]\)

\(f(a,b,c,n)=nm-\sum_{j=0}^{m-1}\ [\frac caj+\frac{c-b-1}a]\)

\(f(a,b,c,n)=nm-f(c,c-b-1,a,m-1)\)

通过这个变化,就可以递归求解了,时间复杂度和朴素欧几里得算法类似

posted @ 2018-02-07 20:33  沛霖  阅读(993)  评论(0编辑  收藏  举报