扩展欧几里得
通解:x+B/GCD*k,y+A/GCD*k
先缩小x1,x2范围,再缩y
#include<bits/stdc++.h>
using namespace std;
void extgcd(long long a,long long b,long long &d,long long &x,long long &y)//return d=gcd(a,b)(==a*x+b*y)
{
if(!b)
d=a,x=1,y=0;
else
{
extgcd(b,a%b,d,y,x);
y-=x*(a/b);
}
}
int main(void)
{
//freopen("in","r",stdin);
int t,Case=0;
long long A,B,C,x1,x2,y1,y2;
long long GCD,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: ",++Case);
if(A==0&&B==0)
{
if(C==0)
printf("%lld\n",(x2-x1+1)*(y2-y1+1));
else
printf("0\n");
continue;
}
if(A==0)
{
if(C%B!=0)
{
printf("0\n");
continue;
}
y=-C/B;
if(y1<=y&&y<=y2)
printf("%lld\n",x2-x1+1);
else
printf("0\n");
continue;
}
if(B==0)
{
if(C%A!=0)
{
printf("0\n");
continue;
}
x=-C/A;
if(x1<=x&&x<=x2)
printf("%lld\n",y2-y1+1);
else
printf("0\n");
continue;
}
extgcd(A,B,GCD,x,y);
x*=-C/GCD;
y*=-C/GCD;
if(C%GCD!=0)
{
printf("0\n");
continue;
}
long long base1=B/GCD;
long long base2=A/GCD;
long long l,r;
x1=((x-x1)%base1+abs(base1))%abs(base1)+x1;
x2=((x-x2)%base1-abs(base1))%abs(base1)+x2;
if(x1>x2)
{
printf("0\n");
continue;
}
l=(-base2)*((x1-x)/base1)+y;
r=(-base2)*((x2-x)/base1)+y;
if(l>r)
swap(l,r);
y1=max(y1,l);
y2=min(y2,r);
y1=((y-y1)%base2+abs(base2))%abs(base2)+y1;
y2=((y-y2)%base2-abs(base2))%abs(base2)+y2;
if(y1>y2)
printf("0\n");
else
printf("%lld\n",(y2-y1)/abs(base2)+1);
}
return 0;
}
lightoj 1306 - Solutions to an Equation
原文地址:http://blog.csdn.net/loolu5/article/details/45935729