sgu106(扩展欧几里得)

来源:互联网 发布:湖北大学知行学院官网 编辑:程序博客网 时间:2024/06/07 17:30

给你7个数,a,b,c,x1,x2,y1,y2.求满足a*x+b*y=-c的解x满足x1<=x<=x2,y满足y1<=y<=y2.求满足条件的解的个数

用扩展欧几里得求得一组解,然后用特解表示通解,这样解出根据x1,x2,y1,y2,解出k,解出k的时候注意变号,也要注意a=0或者b=0,或者c=0的情况,


#include<set>#include<queue>#include<cmath>#include<cstdio>#include<vector>#include<string>#include<utility>#include<cstring>#include<iostream>#include<algorithm>#include<functional>#define MM 1200010#define Inf (1<<30)#define LL long long#define MOD 1000000009#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;LL ceil_div(LL x,LL y){    return ceil(double(x)/double(y));}LL floor_div(LL x,LL y){    return floor(double(x)/double(y));}LL exgcd(LL a, LL b, LL &x, LL &y){if (b == 0){x = 1; y = 0;return a;}LL g = exgcd(b, a%b, x, y);LL u = x;x = y;y = u - a / b*y;return g;}int main(){LL a, b, c;LL xx1, xx2, yy1, yy2;//freopen("D:\\oo.txt", "r", stdin);while (~scanf("%lld%lld%lld%lld%lld%lld%lld", &a, &b, &c, &xx1, &xx2, &yy1, &yy2)){if(a==0&&b==0){            if(c==0)printf("%lld\n", (yy2 - yy1+1)*( xx2 - xx1+1));            else puts("0");}else if (b == 0 && a != 0){if (c%a==0&&xx1 <= -c / a&&-c / a <= xx2)printf("%lld\n", yy2 - yy1+1);else puts("0");}else if (a == 0 && b != 0){if (c%b==0&&yy1 <= -c / b&&-c / b <= yy2)printf("%lld\n", xx2 - xx1+1);else puts("0");}else{    LL x, y;            LL g = exgcd(a, b, x, y);            if (-c%g != 0)puts("0");            else {                LL d=-c/g;                a/=g;b/=g;                x*=d;y*=d;                LL X1,Y1,X2,Y2;                if(b>0)X1=ceil_div(xx1-x,b),Y1=floor_div(xx2-x,b);                else X1=ceil_div(xx2-x,b),Y1=floor_div(xx1-x,b);                if(a>0)X2=ceil_div(y-yy2,a),Y2=floor_div(y-yy1,a);                else X2=ceil_div(y-yy1,a),Y2=floor_div(y-yy2,a);                LL res=min(Y1,Y2)-max(X1,X2)+1;                if(res>=0)printf("%lld\n",res);                else puts("0");            }}}return 0;}


0 0