bzoj 5027: 数学题

题意:

给出a,b,c,x1,x2,y1,y2,求满足ax+by+c=0,且x∈[x1,x2],y∈[y1,y2]的整数解有多少对?

题解:

没什么好说的,就是拓展欧几里得,注意下边界,特判0。
因为没用想好再写,代码贼丑,强烈不建议参考。
code:

#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#define LL long long
using namespace std;
const LL inf=(1<<28);
LL a,b,c,X1,x2,Y1,y2;
LL exgcd(LL a,LL b,LL &x,LL &y)
{
    if(a==0) {x=0;y=1;return b;}
    LL tx,ty,d=exgcd(b%a,a,tx,ty);
    x=ty-(b/a)*tx;y=tx;
    return d;
}
LL down(LL a,LL b)
{
    if(a%b==0) return a/b;
    if(a*b>0) return a/b;
    return a/b-1;
}
LL up(LL a,LL b)
{
    if(a%b==0) return a/b;
    if(a*b>0) return a/b+1;
    return a/b;
}
LL get_l(LL a,LL b) {return up(a,b);}
LL get_r(LL a,LL b) {return down(a,b);}
int main()
{
    scanf("%lld %lld %lld %lld %lld %lld %lld",&a,&b,&c,&X1,&x2,&Y1,&y2);
    if(a==0&&b==0)
    {
        if(c==0) printf("%lld",(x2-X1+1)*(y2-Y1+1));
        else printf("0");
        return 0;
    }
    if(b==0) swap(a,b),swap(X1,Y1),swap(x2,y2);
    c=-c;if(c<0) a=-a,b=-b,c=-c;
    LL x,y,d=exgcd(a,b,x,y);
    if(c%d!=0) {printf("0\n");return 0;}
    if(d<0) d=-d,x=-x,y=-y;
    LL A=a/d,B=b/d,C=c/d;
    x=(x*C%abs(B)+abs(B))%abs(B);
    y=(C-A*x)/B;
    LL l1,r1,l2,r2;
    if(A==0)
    {
        if(Y1<=C/B&&C/B<=y2) printf("%lld",x2-X1+1);
        else printf("0");
        return 0;
    }
    else
    {
        if(B>0) {l1=get_l(X1-x,B);r1=get_r(x2-x,B);}
        else {r1=get_r(X1-x,B);l1=get_l(x2-x,B);}
        if(A<0) {l2=get_l(Y1-y,-A);r2=get_r(y2-y,-A);}
        else {r2=get_r(Y1-y,-A);l2=get_l(y2-y,-A);}
    }
    l1=max(l1,l2);r1=min(r1,r2);
    if(l1>r1) printf("0");
    else printf("%lld",r1-l1+1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值