# include <bits/stdc++.h>
# define int long long
using namespace std;
int exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1,y=0;
return a;
}
int g=exgcd(b,a%b,y,x);
y-=a/b*x;
return g;
}
signed main()
{
int a,b,c,x1,y1,x2,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;
}
int ans=0;
if(a==0&&b==0)
{
if(c==0)
{
ans=(y2-y1+1)*(x2-x1+1);
}
else
{
ans=0;
}
}
else if(a==0)
{
if(c%b==0&&y1<=c/b&&c/b<=y2)
{
ans=x2-x1+1;
}
else
{
ans=0;
}
}
else if(b==0)
{
if(c%a==0&&x1<=c/a&&c/a<=x2)
{
ans=y2-y1+1;
}
else
{
ans=0;
}
}
else
{
int x,y,x0,y0;
int g=exgcd(a,b,x0,y0);
if(c%g!=0)
{
ans=0;
}
else
{
int x3=b/g;
int y3=a/g;
x0=x0*c/g;
y0=y0*c/g;
int k=min(floor(1.0*(x2-x0)/x3),floor(1.0*(y0-y1)/y3));
int k1=max(ceil(1.0*(x1-x0)/x3),ceil(1.0*(y0-y2)/y3));
if(k>=k1)
{
ans=k-k1+1;
}
else
{
ans=0;
}
}
}
cout<<ans<<endl;
}
思路:扩展欧几里得
欧几里得:
用来求a,b的最大公约数而且还能求ax+by=gcd(a,b)的一组解。
ax1+by1=gcd(a,b),bx2+(a mod b)y2=gcd(b,a mod b)
因为由欧几里得算法可知,gcd(a,b)=gcd(b,a mod b)
ax1+by1=bx2+(a mod b)y2;(1)
a mod b=a-a/b*b;(2)
将(1)(2)联立可以得到
x1=y2
y1=x2-(a/b)*y2
2:用来求解ax+by=c;
如果c不是gcd(a,b)的倍数无解
然后方程俩边同时除以gcd(a,b)
g=gcd(a,b)
a1=a/g;b1=b/g;c1=c/g;
接下来只用求a1*x+b1*y=c1的解;
然后a1和b1互质;即:gcd(a1,b1)=1;
求a1*x+b1*y=1;的解;
利用欧几里得求出其中一组解x,y;
则a1*x+b1*y=c1的解为x0,y0;
x0=x*c1;
y0=y*c1;
这也是ax+by=c的解;
ax0+by0=c;
a(x0+k*b)+b(y0-k*a)=c;
得到通解:
x=x0+k*b
y=y0-k*a (k∈Z)
除此以外本题需要进行注意a,b是否为0的问题,并且注意a,b,c;
的大小问题;详情请见代码
注意还有解的取值问题;