题意:给出式子,问x,y在范围内的解的个数。
1:如果a==0&&b==0,c==0有解,否则无解。
2.否则(本题没有a==0或者b==0的数据) a!=0&&b!=0。用ex_gcd得出,abs(a)x+abs(b)y==gcd(abs(a),abs(b)),时x,y的特解,记d=gcd(abs(a),abs(b))。用-c/d乘x,y得到abs(a)x+abs(b)y==-c的特解。如果a<0,x*=-1,b<0,y*=-1,得到ax+by==-c的特解。记为x0,y0。a,b同号的情况下,x0+k(b/d),y0-k(a/d)还是解。那么就看两者k各能取多少,得出交集就行了。具体来说,x0+k(b/d)>=x1,x0+k(b/d)<=x2得出k的取值[kx1,kx2],再得出[ky1,ky2]取交。注意在>=且b>=0时,向上取整
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <iomanip> #include <cstring> #include <map> #include <queue> #include <set> #include <cassert> using namespace std; const double EPS=1e-8; typedef long long lon; const lon SZ=120,INF=0x7FFFFFFF; void ex_gcd(lon &x,lon &y,lon a,lon b,lon &d) { if(b==0) { d=a; x=1,y=0; return; } ex_gcd(y,x,b,a%b,d); y-=a/b*x; } lon func(lon sgn,double val,lon g) { return (!((sgn>0)^g))?ceil(val):floor(val); } int main() { //cout<<ceil(-10.3)<<endl; std::ios::sync_with_stdio(0); //freopen("d:\\1.txt","r",stdin); lon a,b,c,x1,x2,y1,y2,x,y,d; cin>>a>>b>>c>>x1>>x2>>y1>>y2; if(a==0&&b==0) { if(c==0)cout<<((x2-x1+1)*(y2-y1+1))<<endl; else cout<<0<<endl; } else if(b==0) { //if(c/a==(lon)(1.0*c/a))cout<<1<<endl; //else cout<<0<<endl; } else { c*=-1; ex_gcd(x,y,abs(a),abs(b),d); //cout<<x<<" "<<y<<endl; if(c%d) { cout<<0<<endl; } else { x*=c/d; y*=c/d; if(a<0)x*=-1; if(b<0)y*=-1; //cout<<x<<" "<<y<<endl; lon addx=b/d,addy=-a/d; //cout<<addx<<" "<<addy<<endl; lon kx1=func(addx,1.0*(x1-x)/addx,1); lon kx2=func(addx,1.0*(x2-x)/addx,0); lon ky1=func(addy,1.0*(y1-y)/addy,1); lon ky2=func(addy,1.0*(y2-y)/addy,0); //cout<<" "<<addy<<" "<<1.0*(y2-y)/addy<<endl; if(addx<0)swap(kx1,kx2); if(addy<0)swap(ky1,ky2); //cout<<kx1<<" "<<kx2<<" "<<ky1<<" "<<ky2<<endl; lon res1=max(kx1,ky1),res2=min(kx2,ky2); cout<<max(0LL,res2-res1+1)<<endl; } } return 0; }
还有其他情况。