5027: 数学题 扩展欧几里得

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

题解:

直接exgcd求出一组解之后乱搞就行了,注意对a,b等于0、正负数的处理就行了。

代码:

#include
using namespace std;
#define LL long long
#define pa pair
LL read()
{
    LL x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    return x*f;
}
LL exgcd(LL a,LL b,LL &x,LL &y)
{
    if(!a){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 a,b,c,X1,X2,Y1,Y2;
int main()
{
    a=read(),b=read(),c=-read(),X1=read(),X2=read(),Y1=read(),Y2=read();
    if(!a&&!b&&!c)return printf("%lld",(X2-X1+1)*(Y2-Y1+1)),0;
    if(!a&&!b&&c!=0)return puts("0"),0;
    LL x,y,d=exgcd(a,b,x,y);
    if(c%d)return puts("0"),0;
    x*=(c/d),y*=(c/d);
    if(!a)
    {
        if(c%b==0&&Y1<=c/b&&c/b<=Y2)printf("%lld",X2-X1+1);
        else puts("0");
        return 0;
    }
    if(!b)
    {
        if(c%a==0&&X1<=c/a&&c/a<=X2)printf("%lld",Y2-Y1+1);
        else puts("0");
        return 0;
    }
    LL mnx,mxx,mny,mxy;
    if(xif((X1-x)%(b/d)==0)mnx=X1;
        else mnx=x+((X1-x)/abs(b/d)+1)*abs(b/d);
    }
    else
    {
        if((x-X1)%(b/d)==0)mnx=X1;
        else mnx=x-(x-X1)/abs(b/d)*abs(b/d);
    }
    if(xif((X2-x)%(b/d)==0)mxx=X2;
        else mxx=x+((X2-x)/abs(b/d))*abs(b/d);
    }
    else
    {
        if((x-X2)%(b/d)==0)mxx=X2;
        else mxx=x-((x-X2)/abs(b/d)+1)*abs(b/d);
    }
    if(mnxX2||mxxX2)return puts("0"),0;
    if(yif((Y1-y)%(a/d)==0)mny=Y1;
        else mny=y+((Y1-y)/abs(a/d)+1)*abs(a/d);
    }
    else
    {
        if((y-Y1)%(a/d)==0)mny=Y1;
        else mny=y-(y-Y1)/abs(a/d)*abs(a/d);
    }
    if(yif((Y2-y)%(a/d)==0)mxy=Y2;
        else mxy=y+((Y2-y)/abs(a/d))*abs(a/d);
    }
    else
    {
        if((y-Y2)%(a/d)==0)mxy=Y2;
        else mxy=y-((y-Y2)/abs(a/d)+1)*abs(a/d);
    }
    if(mnyY2||mxyY2)return puts("0"),0;
    LL lx=(c-b*mny)/a,rx=(c-b*mxy)/a;if(lx>rx)swap(lx,rx);
    mnx=max(mnx,lx),mxx=min(mxx,rx);
    if(mxx>=mnx)printf("%lld",(mxx-mnx)/abs(b/d)+1);
    else puts("0");
}

你可能感兴趣的:(数论)