POJ 2891 Strange Way to Express Integers
解一般的同余方程组
这里有讲解
http://www.cnblogs.com/Mr-WolframsMgcBox/p/7868283.html
exgcd所算出来的解是最接近于 0 的解
所以输出同余方程的解的时候要 : \((x += x/gcd(x, p)) \%= gcd(x, p)\)
因为我们要求的是最小解,所以每次合并的时候要取模,但是不能改变他的正负
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define ll long long
using namespace std;
ll n, a, b, a1, b1;
ll exgcd(ll a, ll b, ll &x, ll &y) {
if(!b){
x = 1; y = 0;
return a;
}
ll t = exgcd(b, a % b, x, y);
ll k = y;
y = x - a / b * y;
x = k;
return t;
}
int main() {
while(cin >> n){
bool f = 0;
cin >> a >> b;
for(int i = 2; i <= n; i++) {
cin >> a1 >> b1;
if(!f) {
ll x, y;
ll t = exgcd(a, a1, x, y);
if(((b - b1) % t)) {f = 1;continue;}
(x *= ((b - b1) / t)) %= a1;
b = b - a * x;
a = a / t * a1;
b %= a;
}
}
if(f) cout<<-1<<endl;
else cout<<(b + a) % a<<endl;
}
return 0;
}