数论整理之欧几里得算法gcd

简介: 数论整理之欧几里得算法gcd

辗转相除

使用到的原理很聪明也很简单,假设用f(x, y)表示x,y的最大公约数,取k = x/y,b = x%y,则x = ky + b,如果一个数能够同时整除x和y,则必能同时整除b和y;而能够同时整除b和y的数也必能同时整除x和y,即x和y的公约数与b和y的公约数是相同的,其最大公约数也是相同的,则有f(x, y)= f(y, x % y)(y > 0),如此便可把原问题转化为求两个更小数的最大公约数,直到其中一个数为0,剩下的另外一个数就是两者最大的公约数。gcd递归定理是指gcd(a,b)=gcd(b,a%b)


//直接调用
#include <iostream>
#include <algorithm>
using namespace std;
int a,b;
int main()
{
  cin>>a>>b;
  cout<<__gcd(a,b)<<endl;
  return 0;
}
//
int gcd(int a,int b){
  if (b == 0) return a;
  else return gcd(b,a % b);
 }

高精度gcd

(更相减损术)

不妨设a<=b,则有:

1.a=b时, gcd(a,b)=a;

2.a,b均为偶数时,gcd(a,b)=2*gcd(a/2,b/2);

3.a为偶,b为奇时,gcd(a,b)=gcd(a/2,b);

4.a为奇,b为偶时,gcd(a,b)=gcd(a,b/2);

5.a,b均为奇数时,gcd(a,b)=gcd(a-b,b);


//输入两个数(分两行)输出最大公约数
#include<bits/stdc++.h>
#define str strlen 
#define ll long long 
using namespace std;
struct huge{
    int num[10010];
    int len;
};
huge a,b;
char d[10010];char c[10010];
void print(huge x){
    for(int i=x.len-1;i>=0;i--) cout<<x.num[i];
//  cout<<endl;
}
int smp (huge x,huge y){
    if(x.len>y.len)   return 1;
    if(x.len<y.len)   return 2;
    for(int i=x.len-1;i>=0;i--){
        if(x.num[i]>y.num[i]) return 1;
        if(x.num[i]<y.num[i]) return 2;
    }
    return 3;
}
huge ch(huge x){
    int plus=0;
    for(int i=0;i<=x.len-1;i++){
      x.num[i]*=2;
      x.num[i]+=plus;plus=0;
      if(x.num[i]>=10){
        plus=x.num[i]/10;
            x.num[i]%=10;
        }
    }
    if(plus!=0){
        x.len++;
        x.num[x.len-1]=plus;
    } 
    return x;
}
huge chu(huge x){
    for(int i=x.len-1;i>=0;i--){
        if(x.num[i]%2==1){
            x.num[i]--;
            x.num[i-1]+=10;
        }
        x.num[i]/=2;
    }
    while(x.num[x.len-1]==0&&x.len>1) x.len--;
    return x;
}
huge minu(huge x,huge y){
    for(int i=0;i<x.len;i++){
        if(x.num[i]<y.num[i]){
            x.num[i]+=10;
            x.num[i+1]--;
        }
        x.num[i]-=y.num[i];
    } 
    while(x.num[x.len-1]==0&&x.len>1) x.len--;
    return x;
}
void gcd(huge x,huge y){
    int xx=smp(x,y),aa=1-x.num[0]%2,bb=1-y.num[0]%2;
    int tt=0;
    while(xx<3){//print(x);print(y);
        if(xx==2){
            swap(x,y);
            swap(aa,bb);
        }
        if(aa==1&&bb==1){
            x=chu(x);y=chu(y);
            tt++;
        }
        if(aa==1&&bb==0)  x=chu(x);       
        if(aa==0&&bb==1)  y=chu(y);
        if(aa==0&&bb==0)  x=minu(x,y);  
      xx=smp(x,y);aa=1-x.num[0]%2;bb=1-y.num[0]%2;
    }
    for(int i=1;i<=tt;i++)  x=ch(x);
    print(x);
    return;
}
int main(){
    scanf("%s",&c);
    scanf("%s",&d);
    if(str(c)<str(d)||(str(c)==str(d)&&strcmp(d,c)>0)) swap(c,d);
    a.len=str(c);b.len=str(d);
    for(int i=0;i<a.len;i++)
        a.num[i]=(int)(c[a.len-i-1]-'0');
    for(int i=0;i<b.len;i++)
        b.num[i]=(int)(d[b.len-i-1]-'0');
    gcd(a,b);
    return 0;
}
//循环
ll gcd(ll a,ll b)
{
    ll t;
    while(b)///当b为0时,得出结果,a既为结果
    {
        t=b;///存b
        b=(a%b);///b为a对b取模
        a=t;///a为上一次的b
    }
    return a;
}

贝祖定理:其内容是若设a,b是整数,则存在整数x,y,使得ax+by=gcd(a,b),(a,b)代表最大公因数,则设a,b是不全为零的整数,则存在整数x,y,使得ax+by=(a,b)。

| 介是什么符号:

若b可被a整除,或a整除b,则可记作a|b

如2|6,8|16

性质:①a|b,b|c => a|c

②a|b,a|c => a|(b+c)=>a|(mb+nc) (m,n∈Z)

③a|b(a≠0) =>|a|≤|b|


90.png


相关文章
|
3月前
【刷题记录】最大公因数,最小公倍数(辗转相除法、欧几里得算法)
【刷题记录】最大公因数,最小公倍数(辗转相除法、欧几里得算法)
|
6月前
|
算法 数据安全/隐私保护
什么是扩展欧几里得算法?
【5月更文挑战第13天】什么是扩展欧几里得算法?
106 3
|
5月前
|
算法 安全 数据挖掘
解锁编程之门:数论在算法与加密中的实用应用
解锁编程之门:数论在算法与加密中的实用应用
宝藏例题(欧几里得算法+素数的三种境界………)
宝藏例题(欧几里得算法+素数的三种境界………)
宝藏例题(欧几里得算法+素数的三种境界………)
|
6月前
|
算法 Python
Python欧几里得算法找最大公约数
Python欧几里得算法找最大公约数
60 0
|
6月前
|
算法 搜索推荐 程序员
C语言第二十二练——扩展欧几里得算法
C语言第二十二练——扩展欧几里得算法
62 0
P4057 [Code+#1]晨跑(数学分析,辗转相除法模板(欧几里得算法))
P4057 [Code+#1]晨跑(数学分析,辗转相除法模板(欧几里得算法))
54 0
|
算法 搜索推荐 程序员
欧几里得算法
欧几里得算法(Euclidean algorithm)是一种计算两个数的最大公约数(Greatest Common Divisor,简称 GCD)的算法。欧几里得算法的基本思想是通过辗转相除的方式,将两个数逐步缩小,直到它们的公约数为止。欧几里得算法的时间复杂度为 O(log n)。
224 1
|
算法 Java
欧几里得算法(GCD, 辗转相除法)
欧几里得算法(GCD, 辗转相除法)
|
15天前
|
算法 安全 数据安全/隐私保护
基于game-based算法的动态频谱访问matlab仿真
本算法展示了在认知无线电网络中,通过游戏理论优化动态频谱访问,提高频谱利用率和物理层安全性。程序运行效果包括负载因子、传输功率、信噪比对用户效用和保密率的影响分析。软件版本:Matlab 2022a。完整代码包含详细中文注释和操作视频。