您的位置:首页 > 其它

SGU 106 The equation(扩展欧几里德)

2017-11-14 19:19 253 查看
没想起来怎么做


参考:https://www.cnblogs.com/zjbztianya/archive/2013/03/12/2956835.html

思路还是很简单的,ax+by=c, gcd(a,b)=d,则x = x0+(b/d) * t,y = y0 - (a/d) * t,每个t确定一对解,现在已经知道x1<=x<=x2,y1<=y<=y2,代换一下,求出来t的范围即可,有多少个t的整数解,结果就是几。

#include <bits/stdc++.h>
using namespace std;
long long extend_gcd(long long a,long long b,long long &x,long long &y)
{
if(a==0&&b==0) return -1;//无最大公约数
if(b==0)
{
x=1;
y=0;
return a;
}
long long d=extend_gcd(b,a%b,y,x);
y-=a/b*x;
return d;
}

int main()
{
long long a,b,c,x1,y1,x2,y2,x,y,tx,ty,d,l,r;
scanf("%lld %lld %lld %lld %lld %lld %lld",&a,&b,&c,&x1,&x2,&y1,&y2);
if(a == 0 && b == 0)
{
if(c == 0)  printf("%lld\n",(x2-x1+1)*(y2-y1+1));
else printf("0\n");
}
else if(a == 0)
{
if(c%b == 0 && (c/b) >= y1 && (c/b) <= y2) printf("%lld\n",x2-x1+1);
else printf("0\n");
}
else if(b == 0)
{
if(c%a == 0 && (c/a) >= x1 && (c/a) <= x2) printf("%lld\n",y2-y1+1);
else printf("0\n");
}
else
{
c = -c;
if(c < 0)
{
c = -c;
a = -a;
b = -b;
}
if(a < 0)
{
a = -a;
x1 = -x1, x2 = -x2;
swap(x1,x2);
}
if(b < 0)
{
b = -b;
y1 = -y1, y2 = -y2;
swap(y1,y2);
}
d = extend_gcd(a,b,x,y);
if(c%d) printf("0\n");
else
{
tx = x*(c/d);
ty = y*(c/d);
l = max(ceil((double)(x1-tx)*d/b), ceil((double)(ty-y2)*d/a));
r = min(floor((double)(x2-tx)*d/b), floor((double)(ty-y1)*d/a));
if(l > r) printf("0\n");
else printf("%lld\n",r-l+1);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: