题意:给出方程ax+by+c=0,求出有多少对整数解(x,y),满足X1<=x<=X2,
Y1<=y<=Y2;
思路:
扩展欧几里得。
若a=0,b=0,c=0,为(X2-X1+1)*(Y2-Y1+1);
若a=0,b=0,c!=0或c%gcd(a,b)!=0,则无解;
否则,计算满足条件的x所在区间,满足条件的y所在区间,求两区间交集的元素的个数;
在SGU上PE了,未找到坑点。。。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long int64;
int64 exgcd(int64 a,int64 b,int64 &x,int64 &y){
if(!b){
x=1,y=0;
return a;
}
else{
int64 ret=exgcd(b,a%b,y,x);
y-=a/b*x;
return ret;
}
}
int64 a,b,c,X1,X2,Y1,Y2;
int main(){
scanf("%I64d%I64d%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&X1,&X2,&Y1,&Y2);
c*=-1;
int64 x,y,r,dx,dy;
r=exgcd(a,b,x,y);
if(r==0){
if(c==0) printf("%I64d\n",(X2-X1+1)*(Y2-Y1+1));
else printf("0\n");
return 0;
}
if(c%r!=0){
printf("0\n");
return 0;
}
x*=c/r;y*=c/r;
dx=b/r;dy=a/r*(-1);
int64 lx,ly,rx,ry;
X1-=x,X2-=x,Y1-=y,Y2-=y;
if(dx>0)
lx=ceil(double(X1)/dx),rx=floor(double(X2)/dx);
else lx=ceil(double(X2)/dx),rx=floor(double(X1)/dx);
if(dy>0)
ly=ceil(double(Y1)/dy),ry=floor(double(Y2)/dy);
else ly=ceil(double(Y2)/dy),ry=floor(double(Y1)/dy);
int64 lp=max(lx,ly),rp=min(rx,ry);
if(rx<lx||ry<ly||rp<lp) printf("0\n");
else printf("%I64d\n",rp-lp+1);
return 0;
}