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所有 转载请注明出处