坑點:在處理閉區間邊界時,涉及到取ceil和floor的問題,當a>0,b>0時,a/b取floor,可以用(a-1)/b+1取ceil,而a<0,b>0時,a/b取ceil,可以用(a+1)/b-1取floor,a=0特殊考慮,直接a/b就行。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
void ExEuclid(LL a,LL b,LL &x,LL &y,LL &d)
{
if(b==0)
{
d=a,x=1,y=0;
return ;
}
else
{
ExEuclid(b,a%b,x,y,d);
LL t=x;
x=y;
y=t-a/b*y;
return ;
}
}
LL Work(LL a,LL b,LL c,LL x1,LL x2,LL y1,LL y2)
{
LL l1=x1,r1=x2,l2=y1,r2=y2;
if(a==0&&b==0)
{
if(c!=0)
return 0;
return (x2-x1+1)*(y2-y1+1);
}
if(a==0)
{
if(c%b!=0)
return 0;
if((-c)/b<=y2&&(-c)/b>=y1)
return (x2-x1+1);
return 0;
}
if(b==0)
{
if(c%a!=0)
return 0;
if((-c)/a<=x2&&(-c)/a>=x1)
return (y2-y1+1);
return 0;
}
if(a<0)
{
a=-a;
swap(l1,r1);
l1=-l1,r1=-r1;
}
if(b<0)
{
swap(l2,r2);
l2=-l2,r2=-r2;
b=-b;
}
LL x0,y0,d;
ExEuclid(a,b,x0,y0,d);
if(c%d!=0)
return 0;
c=(-c)/d,a/=d,b/=d;
l1-=c*x0,r1-=c*x0;
if(l1<=0) //注意這裏邊界的處理,l1/=b使得絕對值減小,當l1爲正數時起到floor作用,當l1爲負數時起到ceil作用
l1/=b;
else
l1=(l1-1)/b+1; //只有當l1>=1時才能取到ceil作用
if(r1<0)
{
r1=(r1+1)/b-1;
}
else
r1/=b;
l2-=c*y0,r2-=c*y0;
swap(l2,r2);
l2=-l2,r2=-r2;
if(l2<=0)
l2/=a;
else
l2=(l2-1)/a+1;
if(r2<0)
{
r2=(r2+1)/a-1;
}
else
r2/=a;
LL l=l1,r=r1;
if(l2>l1)
l=l2;
if(r2<r1)
r=r2;
if(l<=r)
return r-l+1;
else
return 0;
}
int main()
{
LL a,b,c,x1,y1,x2,y2;
while(scanf("%lld %lld %lld %lld %lld %lld %lld",&a,&b,&c,&x1,&x2,&y1,&y2)!=EOF)
{
if(x1>x2||y1>y2)
printf("0\n");
else
printf("%lld\n",Work(a,b,c,x1,x2,y1,y2));
}
return 0;
}