扩展的欧几里得算法用于求逆元,常用语求解决模方程的解(最小整数解)相关的问题。
百度百科上有很好的证明:http://baike.baidu.com/view/1478219.htm?fr=aladdin
简单的扩展欧几里得算法的应用(求模方程的解) poj2115;
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<cctype>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<string>
#define ll long long
#define MAX 1000
#define INF INT_MAX
#define eps 1e-6
using namespace std;
ll N;
void ex_gcd(ll a, ll b, ll&d, ll& x, ll& y){ //扩展的欧几里得算法求逆元x;
if (b == 0){
d = a;
x = 1;
y = 0;
return;
}
ex_gcd(b,a%b,d,y,x);
y -= (a/b)*x;
}
//求解a=b(MODn)(a与b同余n)的一个最小整数解
ll modular(int a, int n, int b){
ll x, y, d;
ex_gcd(a,N,d,x,y);
if (b % d == 0){
x = (x* (b/d)) % N ; //模方程的一个解
x = (x + N) % (N/d); //模方程的最小整数解
return x;
}
return -1;
}
int main(){
ll A,B,C,k;
while (scanf("%lld%lld%lld%lld",&A,&B,&C,&k)){
if (k == 0) break;
N = 1LL<<k; //注意此处应用长整型而且要将数字1定义为长整型,区别(ll)1<<k与(ll)(1<<K);
ll b = (B-A + N) % N;
ll a = C;
ll res = modular(a,N,b);
if (res < 0) printf("FOREVER\n");
else printf("%lld\n",res);
}
return 0;
}