扩展欧几里得的应用
但是精度确实是被卡成Dog
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef __int64 LL;
LL gcd(LL a,LL b)
{return b==0?a:gcd(b,a%b);}
void gcdex(LL a, LL b, LL &d, LL &x, LL &y) {
if(!b) d = a, x = 1, y = 0;
else gcdex(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, x1 = -x1, x2 = -x2, swap(x1,x2);
if(b < 0) b = -b, y1 = -y1, y2 = -y2, swap(y1,y2);//负数取余不正确,换边界
if(a == 0 && b == 0) {
if(c == 0) cout << (x2 - x1 +1) * (y2 -y1+1) << endl;
else cout << 0 << endl;
}
else if(a == 0) {
if(c % b == 0 && (c/b) >= y1 && (c/b) <= y2) cout << (x2 - x1 +1) << endl;
else cout << 0 << endl;
}
else if(b == 0) {
if(c % a == 0 && (c/a) >= x1 && (c/a) <= x2) cout << (y2- y1 + 1) << endl;
else cout << 0 << endl;
}
else {
if((c % gcd(a,b)) != 0) cout << 0 << endl;
else {
LL x,y,d;
gcdex(a,b,d,x,y);
double LX,LY,RX,RY;
LL L,R;
a = a / d; b = b / d;// a' b'
x *= (c / d);y *= (c / d); // 特解
RX = floor(double(x2 - x*1.0) / (double)b); LX = ceil(double(x1 - x*1.0) / (double)b); // k 在 x1x2 的取值范围
RY = floor(double(y - y1*1.0) / (double)a); LY = ceil(double(y - y2*1.0) / (double)a); // k 在 y1y2 的取值范围
R = min(RX,RY), L = max(LX,LY); // 注意精度问题 当 K > 1.X 时 在LL 默认为 K 为 1 但是实际取 2 0.0
if(R < L) cout << 0 << endl;
else {
//if(R < 0) L = -L, R = -R, swap(L,R);
cout << R - L + 1 << endl;
}
}
}
}
return 0;
}