bzoj 5027: 数学题
发布日期:2021-05-06 23:52:08 浏览次数:21 分类:原创文章

本文共 2126 字,大约阅读时间需要 7 分钟。

题意

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

题解

就一个裸的扩展欧几里得。。。
但是要特判的情况有点多。。
为了方便,我固定了一开始的x是刚刚好小于x1的
这样的话情况会少一点

CODE:

#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>using namespace std;typedef long long LL;LL exgcd (LL a,LL b,LL &x,LL &y){    if (a==0)   {  y=1;x=0;return b;}    LL tx,ty;    LL d=exgcd(b%a,a,tx,ty);    x=ty-(b/a)*tx;y=tx;    return d;}int main(){    LL a,b,c,x1,x2,y1,y2;    scanf("%lld%lld%lld%lld%lld%lld%lld",&a,&b,&c,&x1,&x2,&y1,&y2);    if (x1>x2||y1>y2)    {        printf("0");        return 0;    }    c=-c;    if (a==0&&b==0)    {        if (c!=0)  printf("0\n");        else printf("%lld\n",max(0LL,(x2-x1+1)*(y2-y1+1)));        return 0;    }    if (a==0)    {        LL g=c/b;        if (g*b==c&&g>=y1&&g<=y2) printf("%lld\n",max(0LL,x2-x1+1));        else printf("0");        return 0;    }    if (b==0)    {        LL g=c/a;        if (g*a==c&&g>=x1&&g<=x2) printf("%lld\n",max(0LL,y2-y1+1));        else printf("0");        return 0;    }    //ax+by=-c;    LL x,y;    LL d=exgcd(a,b,x,y);    if (c%d!=0) {  printf("0\n");return 0;}    x=(x*(c/d)%(b/d)+(b/d))%(b/d);      LL xx=b/d,yy=-a/d;//两个东西    if (xx<0) {xx=-xx;yy=-yy;}    //每一次可以变多少     if (x>=x1)    {        LL t=(x-x1)/xx;//先变下来        x=x-t*xx;if (x>=x1) x-=xx;    }    else    {        LL t=(x1-x-1)/xx;        x=x+t*xx;    //  printf("OZY:%d\n",x);        if (x+xx<x1) x+=xx;    }    y=(c-a*x)/b;//先解出两个解//  printf("YES:%lld %lld %lld %lld\n",x,y,xx,yy);    LL ans=(x2-x)/xx;//x范围可以变大多少    if (y>y2)//要缩小     {        if (yy>0) ans=0;        else        {        //  printf("YES\n");            LL lalal=(y1-y)/yy;            ans=min(ans,lalal);            ans=ans-(y2-y+1)/yy;        }    }    else if(y<y1)//要变大    {        if (yy<0) ans=0;        else        {        //  printf("YES\n");            LL lalal=(y2-y)/yy;            ans=min(ans,lalal);            ans=ans-(y1-y-1)/yy;        }    }    else//随便变?     {    //  printf("YES\n");        if (yy>0) ans=min(ans,(y2-y)/yy);        else ans=min(ans,(y1-y)/yy);    }    ans=max(ans,0LL);    printf("%lld\n",ans);    return 0;}
上一篇:NOIPDAY2T2 宝藏
下一篇:bzoj 3011: [Usaco2012 Dec]Running Away From the Barn

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2025年04月11日 02时05分22秒