SGU_106 The equation 同余方程

来源:互联网 发布:mac共享文件夹在哪 编辑:程序博客网 时间:2024/06/06 15:46

http://acm.sgu.ru/problem.php?contest=0&problem=106

题意:

给你一个 ax+by+c = 0的方程, 然后分别给你x、y的区间[x1 , x2] , [y1 , y2] 问你x、y都在给

定区间内的解一共有多少组。

思路:

利用扩张欧几里得算法求出:ax + by = gcd(a ,b) = d 的一组解(x0 ,y0),则原方程有解的条件是

d | c,原方程的解是:x0*c/d + i*b/d , y0 - i*a/d ; 最后只要通过简单的判断就可以得出问题的解。

代码:

#include<stdio.h>#include<string.h>#include<math.h>#include<stdlib.h>typedef __int64 LL ;LL a,b,c,x1,yy1,x2,yy2 ;LL ex_gcd(LL a ,LL b, LL& x, LL& y){    if(b == 0){        x = 1 ; y = 0 ;        return a ;    }    LL d = ex_gcd(b,a%b,x,y) ;    LL t = x ;    x = y ;    y = t - a/b*y ;    return d ;}LL MAX(LL a ,LL b){    return a > b ? a : b ;}LL MIN(LL a, LL b){    return a > b ? b : a ;}int main(){    LL x ,y,ans,res_x ,res_y,low_t ,high_t ;    LL low_t1 , high_t1 ;    LL aa, bb ;    while(scanf("%I64d%I64d%I64d",&a,&b,&c) == 3){        scanf("%I64d%I64d%I64d%I64d",&x1,&x2,&yy1,&yy2) ;        c = -c ;        if(a == 0 && b==0){            if(c != 0){                printf("0\n");            }            else{                ans = (x2-x1+1)*(yy2-yy1+1) ;                printf("%I64d\n",ans);            }            continue ;        }        else if(a == 0){            if(c % b != 0){                printf("0\n");            }            else{                ans = x2 - x1 + 1 ;                printf("%I64d\n",ans);            }            continue ;        }        else if(b == 0){            if(c%a != 0){                printf("0\n");            }            else{                ans = yy2 - yy1 + 1 ;                printf("%I64d\n",ans);            }            continue ;        }        LL d = ex_gcd(a,b,x,y) ;        if( c%d != 0 ){            printf("0\n");  continue ;        }        ans = 0 ;        res_x = (c)/d * x ;        res_y = (c)/d * y ;        b /= d ;        a /= d ;        if(b>0){            low_t = ceil( (x1 - res_x )*1.0/b ) ;            high_t = floor( (x2-res_x)*1.0/b ) ;            if(a > 0){                low_t1 = ceil( (res_y-yy2)*1.0/a) ;                high_t1 = floor( (res_y-yy1)*1.0/a ) ;            }            else{                a = -a ;                low_t1 = ceil( (yy1 - res_y)*1.0/a ) ;                high_t1 = floor( (yy2-res_y)*1.0/a ) ;            }            aa = MAX( low_t, low_t1);            bb = MIN( high_t, high_t1);            if(aa > bb){                ;            }            else{                ans += (bb-aa+1) ;            }        }        else{            b = -b ;            low_t = ceil( (res_x -x2)*1.0/b );            high_t = floor( (res_x - x1)*1.0 / b) ;            if(a > 0){                low_t1 = ceil( (res_y-yy2)*1.0/a) ;                high_t1 = floor( (res_y-yy1)*1.0/a ) ;            }            else{                a = -a ;                low_t1 = ceil( (yy1 - res_y)*1.0/a ) ;                high_t1 = floor( (yy2-res_y)*1.0/a ) ;            }            aa = MAX( low_t, low_t1);            bb = MIN( high_t, high_t1);            if(aa > bb){                ;            }            else{                ans += (bb-aa+1) ;            }        }        printf("%I64d\n",ans);    }    return 0 ;}

 

原创粉丝点击