思路:看题就知道用扩展的欧几里得算法做!!!
首先我们可以求出ax+by=gcd(a,b)=g的一个组解(x0,y0).而要使ax+by=c有解,必须有c%g==0.
继而可以得到ax+by=c的一个组解x1=c*x0/g , y1=c*y0/g。
这样可以得到ax+by=c的通解为:
x=x1+b*t;
y=y1-a*t;
再就是要注意符号问题!!!
代码如下:
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
ll gcd_extend(ll a,ll b,ll &x,ll &y)
{
if(b==){
x=;y=;
return a;
}
else{
ll g=gcd_extend(b,a%b,x,y);
ll t=x;
x=y;
y=t-a/b*y;
return g;
}
}
int sign(ll a)
{
if(a==) return ;
return a>?:-;
}
ll ceil(ll a,ll b) //向上取整,注意符号
{
int s=sign(a)*sign(b);
return b/a+(b%a!=&&s>);
}
ll floor(ll a,ll b) //向下取整,注意符号
{
int s=sign(a)*sign(b);
return b/a-(b%a!=&&s<);
}
int main()
{
int t,ca=;
ll a,b,c,x1,x2,y1,y2,x,y;
scanf("%d",&t);
while(t--){
scanf("%lld%lld%lld%lld%lld%lld%lld",&a,&b,&c,&x1,&x2,&y1,&y2);
printf("Case %d: ",++ca);
if(a==&&b==){
if(c==) printf("%lld\n",(x2-x1+)*(y2-y1+));
else printf("0\n");
continue;
}
if(a==){
if(c%b!=){
printf("0\n");
continue;
}
ll tt=-c/b;
if(y1<=tt&&tt<=y2) printf("%lld\n",x2-x1+);
else printf("0\n");
continue;
}
if(b==){
if(c%a!=){
printf("0\n");
continue;
}
ll tt=-c/a;
if(x1<=tt&&tt<=x2) printf("%lld\n",y2-y1+);
else printf("0\n");
continue;
}
ll g=gcd_extend(a,b,x,y);
if(c%g!=){
printf("0\n");
continue;
}
if(sign(g)*sign(b)<) swap(x1,x2);
ll l1=ceil(b,g*x1+c*x);
ll l2=floor(b,g*x2+c*x);
if(sign(-a)*sign(g)<) swap(y1,y2);
ll r1=ceil(-a,g*y1+c*y);
ll r2=floor(-a,g*y2+c*y);
l1=max(l1,r1);
r1=min(l2,r2);
if(l1>r1) printf("0\n");
else printf("%lld\n",r1-l1+);
}
return ;
}