SGU 106.The equation

时间限制:0.25s

内存限制: 4Mib

题目

        有一个方程ax + by + c = 0。 给定a,b,c,x1,x2,y1,y2,你需要得出,有多少整根满足以下条件: x1<=x<=x2, y1<=y<=y2。

输入

        输入包含整数 a,b,c,x1,x2,y1,y2 用空格或者空行隔开。所有数的绝对值不超过10^8。

输出

        输出答案

输入样例

1 1 -3

0 4

0 4

输出样例

4

 

 

{=======================================}

分析:

         题中要求解一个二元一次不定方程,使用拓展欧几里得定理.

     

        另外还要求一个区间内的解

 

       当求出一个特解(x,y)后

       xn =x+k1(b/gcd(a,b);k1为整数

       yn =y+k2(a/gcd(a,b));k2为整数

       

         将给出范围代入,得到k1 和k2 的范围,再取交集,就可以得到答案了。

      

        而且对于a,b中有0存在的情况需要特判。

 

参考代码

#include <iostream>
using namespace std;
typedef __int64  I64;
I64 a, b, c, x1, x2, y1, y2, x, y, ans = 0;
I64 mL[2], mR[2], t = -1;
I64 Exgcd (I64 a, I64 b, I64 &x, I64 &y) {
	if (b == 0) {
		x = 1, y = 0;
		return a;
	}
	I64 temp = Exgcd (b, a % b, x, y);
	I64 t = x;
	x = y;
	y = t - a / b * y;
	return temp;
}
void update (I64 L, I64 R, I64 wa) {
	if (wa < 0) {
		L = -L, R = -R, wa = -wa;
		swap (L, R);
	}
	mL[++t] = (L <= 0) ? L / wa : (L - 1) / wa + 1 ;
	mR[t] = (R >= 0) ? R / wa : (R + 1) / wa - 1 ;
}
int main() {
	cin >> a >> b >> c >> x1 >> x2 >> y1 >> y2;
	c = -c;
	if (a == 0 && b == 0) {
		if (c == 0) ans = (x2 - x1 + 1) * (y2 - y1 + 1);
	}
	else if (a == 0) {
		if (c % b == 0 && c / b >= y1 && c / b <= y2)
			ans = x2 - x1 + 1;
	}
	else if (b == 0) {
		if (c % a == 0 && c / a >= x1 && c / a <= x2)
			ans = y2 - y1 + 1;
	}
	else {
		I64 d = Exgcd (a, b, x, y);
		if (c % d == 0) {
			I64 p = c / d;
			update (x1 - p * x, x2 - p * x, b / d);
			update (y1 - p * y, y2 - p * y, -a / d);
			ans = min (mR[0], mR[1]) - max (mL[0], mL[1]) + 1;
			if (ans < 0) ans = 0;
		}
	}
	cout << ans << endl;
}

http://www.cnblogs.com/keam37/ keam所有 转载请注明出处
posted @ 2014-06-29 09:47  keambar  阅读(326)  评论(0编辑  收藏  举报