There is an equation ax + by + c = 0. Given a,b,c,x1,x2,y1,y2 you must determine, how many integer roots of this equation are satisfy to the following conditions : x1<=x<=x2, y1<=y<=y2. Integer root of this equation is a pair of integer numbers (x,y). |
Input
Input contains integer numbers a,b,c,x1,x2,y1,y2 delimited by spaces and line breaks. All numbers are not greater than 108 by absolute value。
Output
Write answer to the output.
Sample Input
1 1 -3 0 4 0 4
Sample Output
4
大意:给你a,b,c,x1,y1,x2,y2。让你求ax+by+c=0在区间[x1,x2],[y1,y2]的整数解个数。
考虑扩展欧几里得: 得到特解x0,y0后。设a=a/gcd,b=b/gcd。通解为x=x0+b*k,y=y0-a*k;
则 得到不等式 x1<=x+b*k<=x2,y1<=y-a*k<=y2。
解k的范围,取交集就好了。注意考虑向上取整与向下取整。
比如下界就应该是想上取整,上界应该向下取整。
#include <iostream> #include <algorithm> #define maxn 2025 using namespace std; typedef long long ll; ll ans=0; ll L=-1e9,R=1e9; ll ex_gcd(ll a,ll b,ll &x,ll &y) { if(b==0) { x=1; y=0; return a; } ll ans=ex_gcd(b,a%b,x,y); ll temp=x; x=y; y=temp-(a/b)*x; return ans; } ll down(ll x,ll y)//向下取整 { ll res=0; res=x/y; if(x<0||y<0) { if(x%y!=0) { res--; } } return res; } ll upper(ll x,ll y)//向上取整 { ll res=x/y; if(x>0&&y>0||x<0&&y<0) { if(x%y!=0) { res++; } } return res; } void sovle(ll l,ll r,ll b) { if(b<0) { l=-l; r=-r; b=-b; swap(l,r); } L=max(L,upper(l,b)); R=min(R,down(r,b)); } int main() { int n; ll a,b,c,x1,y1,x2,y2; cin>>a>>b>>c>>x1>>x2>>y1>>y2; c=-c; if(a==0&&b==0&&c!=0) { ans=0; } else if(a==0&&b==0&&c==0) { ans=(x2-x1+1)*(y2-y1+1); } else if(a==0&&b!=0) { if(c%b==0) { ll y=c/b; if(y>=y1&&y<=y2) { ans++; } } } else if(b==0&&a!=0) { if(c%a==0) { ll x=c/a; if(x>=x1&&x<=x2) { ans++; } } } else { ll x,y; ll gcd=ex_gcd(a,b,x,y); if(c%gcd==0) { x=x*c/gcd; y=y*c/gcd; a/=gcd; b/=gcd; ll lx=x1-x,rx=x2-x; ll ly=y1-y,ry=y2-y; sovle(lx,rx,b); sovle(ly,ry,-a); ans=R-L+1; } } cout<<ans<<endl; return 0; }