SGU 106

题意:给出方程ax+by+c=0,求出有多少对整数解(x,y),满足X1<=x<=X2,
Y1<=y<=Y2;
思路:
扩展欧几里得。
若a=0,b=0,c=0,为(X2-X1+1)*(Y2-Y1+1);
若a=0,b=0,c!=0或c%gcd(a,b)!=0,则无解;
否则,计算满足条件的x所在区间,满足条件的y所在区间,求两区间交集的元素的个数;
在SGU上PE了,未找到坑点。。。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long int64;
int64 exgcd(int64 a,int64 b,int64 &x,int64 &y){
    if(!b){
        x=1,y=0;
        return a;
    }
    else{
        int64 ret=exgcd(b,a%b,y,x);
        y-=a/b*x;
        return ret;
    }
}
int64 a,b,c,X1,X2,Y1,Y2;
int main(){
    scanf("%I64d%I64d%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&X1,&X2,&Y1,&Y2);
    c*=-1;
    int64 x,y,r,dx,dy;
    r=exgcd(a,b,x,y);
    if(r==0){
        if(c==0) printf("%I64d\n",(X2-X1+1)*(Y2-Y1+1));
        else printf("0\n");
        return 0;
    }
    if(c%r!=0){
        printf("0\n");
        return 0;
    }
    x*=c/r;y*=c/r;
    dx=b/r;dy=a/r*(-1);
    int64 lx,ly,rx,ry;
    X1-=x,X2-=x,Y1-=y,Y2-=y;
    if(dx>0)
        lx=ceil(double(X1)/dx),rx=floor(double(X2)/dx);
    else lx=ceil(double(X2)/dx),rx=floor(double(X1)/dx);
    if(dy>0)
        ly=ceil(double(Y1)/dy),ry=floor(double(Y2)/dy);
    else ly=ceil(double(Y2)/dy),ry=floor(double(Y1)/dy);
    int64 lp=max(lx,ly),rp=min(rx,ry);
    if(rx<lx||ry<ly||rp<lp) printf("0\n");
    else printf("%I64d\n",rp-lp+1);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值