思路:用拓展欧几里的求出方程的一组解,然后求解出其他解,有很多细节的地方需要注意。
注意拓展欧几里得的应用条件。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll x1,x2,y1,y2;
ll exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b)
{
x=1;
y=0;
return a;
}
ll ans=exgcd(b,a%b,x,y);
ll tmp=x;
x=y;
y=tmp-(a/b)*y;
return ans;
}
ll cal(ll a,ll b,ll c)
{
ll x,y;
ll gcd=exgcd(a,b,x,y);
if(c%gcd)
return 0;
x=x/gcd*c;
y=y/gcd*c;
b/=gcd;
a/=gcd;//区间合并:(这样可以减少错误)
ll r1=floor(1.0*(x2-x)/b);
ll l2=ceil(1.0*(y-y2)/a);
ll l1=ceil(1.0*(x1-x)/b);
ll r2=floor(1.0*(y-y1)/a);
ll l=max(l1,l2);
ll r=min(r1,r2);
return l<=r?r-l+1:0;
}
int main()
{
ll a,b,c,ans=0;
scanf("%lld%lld%lld",&a,&b,&c);
scanf("%lld%lld",&x1,&x2);
scanf("%lld%lld",&y1,&y2);
if(c>0)//预处理方便处理
c=-c,a=-a,b=-b;
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(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)
{
ll t=-c/b;
if(b*t+c==0&&t>=y1&&t<=y2)
ans=x2-x1+1;
}
else if(b==0)
{
ll t=-c/a;
if(a*t+c==0&&t>=x1&&t<=x2)
ans=y2-y1+1;
}
else
ans=cal(a,b,-c);
printf("%lld\n",ans);
return 0;
}