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;
}
posted @ 2018-03-11 21:53  Mr_Wolfram  阅读(75)  评论(0编辑  收藏  举报