# 简单的欧几里德与扩展欧几里德

### 1).扩展欧几里德的起手题——NOIP2012.同余方程

void ex_gcd(LL a, LL b,LL &x, LL &y)
{
if (!b){
x = 1; y = 0;
return;
} else {
ex_gcd(b, a % b, x, y);
int t = x;
x = y; y = t - a / b * y;
}
}

### 2).欧几里德的应用——bzoj1385.Division expression

#include <cstdio>

using namespace std;

const int MAX_N = 10005;

int T, n, a[MAX_N];

void init()
{
scanf("%d", &n);
for (int i = 1; i <= n; i ++)
scanf("%d", &a[i]);
}

int gcd(int a, int b)
{
return (b == 0) ? a : gcd(b, a % b);
}

bool judge()
{
a[2] /= gcd(a[1], a[2]);
for (int i = 3; i <= n; i ++) a[2] /= gcd(a[i], a[2]);
if (a[2] == 1) return 1;
return 0;
}

void doit()
{
if (judge()) printf("YES\n");
else printf("NO\n");
}

int main()
{
scanf("%d", &T);
while (T --){
init();
doit();
}
return 0;
}

### 3).更多的扩展欧几里德

#### 1.bzoj1477 && poj1061.青蛙的约会

#include <cstdio>

using namespace std;

typedef long long LL;

long long N, M, x, y, L;

void init()
{
scanf("%lld%lld%lld%lld%lld", &x, &y, &M, &N, &L);
}

LL gcd(LL a, LL b)
{
if (!b) return a;
return gcd(b, a % b);
}

void ex_gcd(LL a, LL b, LL &X, LL &Y)
{
if (!b){ X = 1, Y = 0; return; }
else {
ex_gcd(b, a % b, X, Y);
LL t = X;
X = Y; Y = t - a / b * X;
}
}

void doit(void)
{
LL a = M - N, b = L, c = y - x;
LL g = gcd(a, b);
if (c % g) { printf("Impossible\n"); return; }

LL X, Y;
ex_gcd(a, b, X, Y);
X = X * c / g;
X = (X % b + b) % b;
if (!X) X = b;
printf("%d\n", X);
return;
}

int main(void)
{
init(); doit();
return 0;
}

#### 2.poj2115.C Looooops

for (int i = a; i <= b; i += c, i %= 1 << k)能执行几次。死循环则输出 "FOREVER"

#include <cstdio>

using namespace std;

typedef long long LL;

LL i, j, l, k;

LL gcd(LL a, LL b)
{
return (b == 0) ? a : gcd(b, a % b);
}

void ex_gcd(LL a, LL b,LL &x, LL &y)
{
if (!b){
x = 1; y = 0;
return;
} else {
ex_gcd(b, a % b, x, y);
int t = x;
x = y; y = t - a / b * y;
}
}

void doit()
{
LL a = l, c = j - i, b = 1;
for (int p = 1; p <= k; p ++) b *= 2;
if (a < 0){
a *= -1; b *= -1;
}

LL x, y, d = gcd(a, b);
if (c % d != 0) { printf("FOREVER\n"); return; }

a /= d; b /= d; c /= d;
ex_gcd(a, b, x, y);
x = (((x * c) % b) + b) % b;
printf("%lld\n", x);
}

int main()
{
while (scanf("%lld%lld%lld%lld", &i, &j, &l, &k) != EOF){
if (i == 0 && j == 0 && l == 0 && k == 0) break;
doit();
}
return 0;
}

#### 3.bzoj1407.Savage(NOI2002)

#include <cstdio>
#include <algorithm>

using namespace std;

const int MAX_N = 120;

int n, c[MAX_N], p[MAX_N], l[MAX_N];
int x, y, d, cnt = 0;

void init()
{
scanf("%d", &n);
for (int i = 1; i <= n; i ++) {
scanf("%d%d%d", &c[i], &p[i], &l[i]),
c[i] --,
cnt = max(c[i], cnt);
}
}

void ex_gcd(int a, int b, int &d, int &x, int &y)
{
if (!b){
x = 1; y = 0; d = a;
return;
} else {
ex_gcd(b, a % b, d, x, y);
int t = x;
x = y; y = t - a / b * x;
}
}

bool check(int m)
{
for (int i = 1; i <= n; i ++)
for (int j = i + 1; j <= n; j ++){
int a = p[i] - p[j], b = m, C = c[j] - c[i];
if (a < 0){
a *= -1; C *= -1;
}
ex_gcd(a, b, d, x, y);
if (C % d) continue;
int t = b / d;
x = x * C / d;
while (x < 0) x = x + t;
while (x >= t) x = x - t;
if (x <= l[i] && x <= l[j]) return 0;
}
return 1;
}

void doit()
{
for (int i = cnt + 1; i <= 1000000; i ++)
if (check(i)){ printf("%d\n", i); break; }
return;
}

int main()
{
init();
doit();
return 0;
}

• 本文已收录于以下专栏：

## RSA密码体系中利用扩展的欧几里德算法求解密密钥（源代码）

• 2008年05月25日 08:53
• 579B
• 下载

## 关于扩展欧几里德算法的报告

• 2012年09月13日 18:55
• 427KB
• 下载

## 扩展欧几里德问题

• 2015年12月07日 22:07
• 65KB
• 下载

## 扩展欧几里德算法－－－

• 2008年04月15日 14:53
• 13KB
• 下载

## 扩展欧几里德定理

• 2011年12月17日 15:51
• 81KB
• 下载

## 欧几里德几何教程和java源码

• 2011年11月21日 01:13
• 2.52MB
• 下载

## 求最大公因子（辗转相除法原理）（扩展的欧几里德算法）

while(n != 0) { r = m % n; m = n; n = r; } printf("Their greates...

## 欧几里德算法和仿射密码

• 2010年05月08日 16:17
• 2KB
• 下载

举报原因： 您举报文章：简单的欧几里德与扩展欧几里德 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)