uva 11768

时间:2023-03-09 01:16:25
uva 11768
// 扩展欧几里得算法 
// 先求出一个解 再求出区间 [x1,x2]有几个整数符合条件
// 需要注意的是 水平和垂直2种情况的处理 还有正数和负数取整的细微差别
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <string.h>
using namespace std;
#define MOD 1000000007
#define maxn 1000010
#define maxm 48010
#define LL long long
LL ax,ay,bx,by;
LL a,b,c;
LL d,x,y;
void extendGcd(LL a,LL b){
if(b==){
d=a;
x=;
y=;
}else{
extendGcd(b,a%b);
LL t=x;
x=y;
y=t-a/b*y;
}
}
LL lt(double p){
if(p>){
LL x=p+0.05;x=x*;
LL y=(p+0.05)*;
if(x==y) return x/;
return x/+;
}
else{
return (LL)(p-0.05);
}
}
LL rt(double p){
if(p>=)
return (LL)(p+0.05);
else {
LL x=p-0.05;x=x*;
LL y=(p-0.05)*;
if(x==y) return x/;
return x/-;
}
}
LL get(double d){
if(d>=) return (d+0.05)*;
else return (d-0.05)*;
}
int main(){ int T;
double x1,y1,x2,y2;
LL ax,ay,bx,by;
LL a,b,c;
scanf("%d",&T);
while(T--){
scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
ax=get(x1);ay=get(y1);
bx=get(x2);by=get(y2);
if(ay==by){
if(ay%) { printf("0\n");continue;}
LL lx=lt(min(x1,x2)),rx=rt(max(x1,x2));
if(lx==rx&&ay%){printf("0\n");continue;}
printf("%lld\n",rx-lx+);
continue;
}
else if(ax==bx) {
if(ax%) { printf("0\n");continue;}
LL ly=lt(min(y1,y2)),ry=rt(max(y1,y2));
if(ly==ry&&ax%){printf("0\n");continue;}
printf("%lld\n",ry-ly+);
continue;
} a=(ay-by)*;
b=(bx-ax)*;
c=(bx-ax)*ay-(by-ay)*ax; extendGcd(a,b);
if(c%d!=){printf("0\n");continue;}
x=x*(c/d);
LL m=b/d;
LL lx=lt(min(x1,x2)),rx=rt(max(x1,x2));
if(m<) m=-m;
x=x-(x-lx)/m*m;
x-=m;
while(x<lx)
x+=m;
LL k=(rx-x)/m;
while(x+k*m<=rx) k++;
printf("%lld\n",k);
}
return ;
}