思路:看题就知道用扩展的欧几里得算法做!!!
首先我们可以求出ax+by=gcd(a,b)=g的一个组解(x0,y0).而要使ax+by=c有解,必须有c%g==0.
继而可以得到ax+by=c的一个组解x1=c*x0/g , y1=c*y0/g。
这样可以得到ax+by=c的通解为:
x=x1+b*t;
y=y1-a*t;
再就是要注意符号问题!!!
代码如下:
1 #include<cstdio> 2 #include<algorithm> 3 #define ll long long 4 using namespace std; 5 ll gcd_extend(ll a,ll b,ll &x,ll &y) 6 { 7 if(b==0){ 8 x=1;y=0; 9 return a; 10 } 11 else{ 12 ll g=gcd_extend(b,a%b,x,y); 13 ll t=x; 14 x=y; 15 y=t-a/b*y; 16 return g; 17 } 18 } 19 int sign(ll a) 20 { 21 if(a==0) return 0; 22 return a>0?1:-1; 23 } 24 ll ceil(ll a,ll b) //向上取整,注意符号 25 { 26 int s=sign(a)*sign(b); 27 return b/a+(b%a!=0&&s>0); 28 } 29 ll floor(ll a,ll b) //向下取整,注意符号 30 { 31 int s=sign(a)*sign(b); 32 return b/a-(b%a!=0&&s<0); 33 } 34 int main() 35 { 36 int t,ca=0; 37 ll a,b,c,x1,x2,y1,y2,x,y; 38 scanf("%d",&t); 39 while(t--){ 40 scanf("%lld%lld%lld%lld%lld%lld%lld",&a,&b,&c,&x1,&x2,&y1,&y2); 41 printf("Case %d: ",++ca); 42 if(a==0&&b==0){ 43 if(c==0) printf("%lld ",(x2-x1+1)*(y2-y1+1)); 44 else printf("0 "); 45 continue; 46 } 47 if(a==0){ 48 if(c%b!=0){ 49 printf("0 "); 50 continue; 51 } 52 ll tt=-c/b; 53 if(y1<=tt&&tt<=y2) printf("%lld ",x2-x1+1); 54 else printf("0 "); 55 continue; 56 } 57 if(b==0){ 58 if(c%a!=0){ 59 printf("0 "); 60 continue; 61 } 62 ll tt=-c/a; 63 if(x1<=tt&&tt<=x2) printf("%lld ",y2-y1+1); 64 else printf("0 "); 65 continue; 66 } 67 ll g=gcd_extend(a,b,x,y); 68 if(c%g!=0){ 69 printf("0 "); 70 continue; 71 } 72 if(sign(g)*sign(b)<0) swap(x1,x2); 73 ll l1=ceil(b,g*x1+c*x); 74 ll l2=floor(b,g*x2+c*x); 75 if(sign(-a)*sign(g)<0) swap(y1,y2); 76 ll r1=ceil(-a,g*y1+c*y); 77 ll r2=floor(-a,g*y2+c*y); 78 l1=max(l1,r1); 79 r1=min(l2,r2); 80 if(l1>r1) printf("0 "); 81 else printf("%lld ",r1-l1+1); 82 } 83 return 0; 84 }