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). |
Input
Input contains integer numbers a,b,c,x1,x2,y1,y2 delimited by spaces and line breaks. All numbers are not greater
算法:
ax + by + c = 0
因为,扩展欧几里得处理不了数为负数的情况。所以,要保障a,b,c为整数。下面分析过程:
1、(-a)x + (-b)y = c 需要判断a,b,c的正负值。
c < 0 -----> a = -a,b = -b 取值转变区间[x1,x2]------> [x2,x1] ,[y1,y2] -------->[y2,y1]
a < 0 ------>直接变区间
b < 0 同理
2、判断ax + by = -c ,其中a,b是否为0的情况。因为,这时候是比较特殊的。
1.a = 0 && b = 0 --->c = 0 有解,否则无解
2.a = 0&&b != 0 --> by = -c --->y = -c/b判断 -c % b == 0 && y1 <= y <= y2 ?成立有解,否则无解
3.b = 0&&b !=0 同理
3,ax + by = -c ,其中a != 0 && b != 0,运用扩展欧几里得。求出其中|x| + |y| 的最小解,然后再判断。
x = x0 + kb --> k = (x - x0) / b ----> x1 <= k <= x2
y = y0 - kb ---> k=(y-y0)/b ----> y2 <= k <= y1 (注意负号使得区间转换!!!!!)
最后,取区间的交集就可以了。
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
typedef pair<int,int> P;
inline int read(){
int x = 0,f = 1; char ch = getchar();
while(ch < '0'||ch > '9'){if(ch == '-')f=-1;ch = getchar();}
while(ch >= '0'&&ch <= '9'){x = x * 10 + ch -'0';ch = getchar();}
return x*f;
}
//
inline long long cmin(const long long &x,const long long &y) {return x<y?x:y;}
inline long long cmax(const long long &x,const long long &y) {return x>y?x:y;}
LL gcd(LL a,LL b){
return b ? gcd(b,a%b) : a;
}
void extgcd(LL a,LL b,LL& d,LL& x,LL& y){
if(!b) { d = a; x = 1;y = 0;}
else { extgcd(b,a%b,d,y,x); y -= x*(a/b);}
}
int main()
{
LL a,b,c,x1,x2,y1,y2;
cin >> a >> b >> c >> x1 >> x2 >> y1 >> y2;
c = -c;
if(c < 0) {a = -a; b = -b; c = -c;}
if(a < 0) {a = -a; swap(x1,x2); x1 = -x1; x2 = -x2;}
if(b < 0) {b = -b; swap(y1,y2); y1 = -y1; y2 = -y2;}
if(a == 0&&b == 0){
if(c == 0){
printf("%I64d",(x2-x1+1)*(y2-y1+1));
} else {
printf("0");
}
return 0;
}
if(a == 0){
if(c % b == 0&&y1 <= c/b&&c/b <= y2){
printf("%I64d",x2-x1+1);
} else {
printf("0");
}
return 0;
}
if(b == 0){
if(a % c == 0 && x1 <= c/a&&c/a <= x2){
printf("%I64d",y2-y1+1);
} else {
printf("0");
}
return 0;
}
LL d,x,y;
d = gcd(a,b);
if(c%d){
printf("0");
return 0;
}
a /= d; b /= d; c /= d;
extgcd(a,b,d,x,y);
x *= d; y *= d;
double tx1 = x1,tx2 = x2,ty1 = y1,ty2 = y2,tb = b,ta = a,tx = x,ty = y;
LL downx = floor((tx2 - tx) / tb),downy = floor((ty2 - ty) / ta);
LL upx = ceil((tx1 - tx) / tb),upy = floor((ty1 - ty) / ta);
LL r = cmin(downx,downy);
LL l = cmax(upx,upy);
LL ans;
if(r < l) ans = 0;
else ans = r - l + 1;
printf("%I64d",ans);
return 0;
}
/*
1 1 -3
0 4
0 4
*/
fdf