题意:给出方程ax + by + c = 0,以及a,b,c,x1,x2,y1,y2, 问有多少整数解(x,y)满足x1<=x<=x2,y1<=y<=y2。
Problem:There is an equation ax + by + c = 0. Given a,b,c,x1,x2,y1,y2 you must determine, how many integer roots of this equation are satisfy to the following conditions:x1<=x<=x2,y1<=y<=y2. Integer root of this equation is a pair of integer numbers (x,y).
解法:细节较多要注意。首先处理a,b全零,以及有一个零的情况。对于一般情况,用扩展GCD求出方程ax + by = gcd(a,b)的特解和a,b的gcd。如果题目有解,显然c能整除gcd。之后求出x,y的取值范围。具体方法是,先将特解x,y扩大倍数到匹配参数c,之后利用a,b除去gcd后的互质数对,算出可取区间。
Solution:There are many details need to pay attention. First solving the case when a and b are 0, then a or b is 0. For general, using extend gcd to get the particular solution of ax + by = gcd(a,b) and gcd(a,b). If the problem has a solution, c must be divisible by gcd. After that calculate the range of x and y. Specifically, multiplying x and y to match parameter c, then utilizing the pair of numbers which come from (a,b) divides gcd, to make the range.
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
typedef long long LL;
LL a,b,c,x1,x2,y1,y2,x,y,ans,tmp;
LL exgcd(LL a,LL b,LL &x,LL &y) {
if (b==0) {
x = 1;
y = 0;
return a;
}
LL d = exgcd(b,a%b,x,y);
LL xt = x;
x = y;
y = xt-a/b*y;
return d;
}
int main() {
cin >> a >> b >> c >> x1 >> x2 >> y1 >> y2;
ans = 0;
if (a==0 && b==0) {
if (c==0) ans = (x2-x1+1) * (y2-y1+1);
}
else if (a==0 && b!=0) {
if (c % b==0) {
tmp = -c/b;
if (tmp>=y1 && tmp<=y2) ans = x2-x1+1;
}
}
else if (a!=0 && b==0) {
if (c % a==0) {
tmp = -c/a;
if (tmp>=x1 && tmp<=x2) ans = y2-y1+1;
}
}
else {
LL gcd = exgcd(a,b,x,y);
if (c%gcd==0) {
LL k = -c/gcd;
x = k*x;
y = k*y;
LL aa = b/gcd;
LL bb = a/gcd;
LL lx = (x1 <= x || (x1 - x) % aa == 0) ? ((x1 - x) / aa) : ((x1 - x) / aa + 1);
LL rx = (x2 >= x || (x2 - x) % aa == 0) ? ((x2 - x) / aa) : ((x2 - x) / aa - 1);
LL ly = (y1 <= y || (y - y1) % bb == 0) ? ((y - y1) / bb) : ((y - y1) / bb - 1);
LL ry = (y2 >= y || (y - y2) % bb == 0) ? ((y - y2) / bb) : ((y - y2) / bb + 1);
if (lx > rx) swap(lx, rx);
if (ly > ry) swap(ly, ry);
if (ry >= lx && rx >= ly)
ans = min(rx, ry) - max(lx, ly) + 1;
}
}
cout << ans << endl;
return 0;
}