• sgu106The equation


    这题写了很久了,也看了许多题解。。可是发现都好复杂,看不懂啊,果然智商是硬伤。

    虽然知道这题是扩展欧几里德算法。。但是对与ax+by=c中系数的正负处理的不好,偶然看一题解发现处理的很好就抄袭了过来。Orz大神

    http://blog.csdn.net/jerryihuang/article/details/7992068

    这道题各种坑啊,各种讨论,各种bug,不过倒是学到不少,至少扩展欧几里德会用了,,,泪啊

    //求的是ax+by=gcd(a,b)的解,其中d=gcd(a,b),注意a>b,并且最好把a,b变成正数计算

    void
    exgcd(LL a,LL b,LL &d,LL &x,LL &y) { if(!b){d=a;x=1;y=0;} else{exgcd(b,a%b,d,y,x);y-=x*(a/b);} }

     //先算出ax+by=gcd(a,b)的解x1,y1,d=gcd(a,b),然后ax+by=c的一组解是x=x1*c/d,y=y1*c/d;(注意:若c%d!=0,则无解)

    //又因为若ax+by=c的一组解为(x0,y0),则它的任意解都可以写成(x0+kb',y0-ka'),其中a'=a/gcd(a,b),b'=b/gcd(a,b),k取任意值

    // File Name: 106.cpp
    // Author: zlbing
    // Created Time: 2013/2/28 20:19:38
    
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define CL(x,v); memset(x,v,sizeof(x));
    #define INF 0x3f3f3f3f
    #define LL long long
    void exgcd(LL a,LL b,LL &d,LL &x,LL &y)
    {
        if(!b){d=a;x=1;y=0;}
        else{exgcd(b,a%b,d,y,x);y-=x*(a/b);}
    }
    int main(){
        LL a,b,c,d,x,y,x1,x2,y1,y2;
        while(~scanf("%I64d%I64d%I64d",&a,&b,&c))
        {
            scanf("%I64d%I64d",&x1,&x2);
            scanf("%I64d%I64d",&y1,&y2);
            if(a==0||b==0)
            {
                if(a==0&&b){
                    if(c%b||c/b>y2||c/b<y1)printf("0\n");
                    else {
                        printf("%I64d\n",x2-x1+1);
                    }
                }
                else if(b==0&&a){
                    if(c%a||c/a>x2||c/a<x1)printf("0\n");
                    else {
                        printf("%I64d\n",y2-y1+1);
                    }
                }
                else {
                    if(c==0)printf("%I64d\n",(y2-y1+1)*(x2-x1+1));
                    else printf("0\n");
                
                }
                continue;
            }
            if(c<0)c=-c;
            else{
                a=-a;b=-b;
            }
            if(a<0){
                a=-a;
                x1=-x1;
                x2=-x2;
                swap(x1,x2);
            }
            if(b<0){
                b=-b;
                y1=-y1;
                y2=-y2;
                swap(y1,y2);
            }
            LL d,x,y;
            if(a<b){
                exgcd(b,a,d,y,x);
            }
            else exgcd(a,b,d,x,y);
            if(c%d){
                printf("0\n");
                continue;
            }
            a=a/d;
            b=b/d;
            c=c/d;
            while(x<x1){
                x+=b;
                y-=a;
            }
            while(x>x2){
                x-=b;
                y+=a;
            }
            LL ans=0;
            x=x*c;y=y*c;
            while(x<=x2){
                if(ans)break;
                if(x>=x1&&x<=x2&&y>=y1&&y<=y2)ans++;
                if(ans)break;
                x+=b;y-=a;
            }
            while(x>=x1){
                if(ans)break;
                if(x>=x1&&x<=x2&&y>=y1&&y<=y2)ans++;
                if(ans)break;
                x-=b;y+=a;
            }
         //将x,y暴力加或减,使x,y都在取值区间里
    if(ans){ LL a1=(x2-x)/b;LL b1=(y-y1)/a; ans+=min(a1,b1); a1=(x-x1)/b;b1=(y2-y)/a; ans+=min(a1,b1); } printf("%I64d\n",ans); } return 0; }
  • 相关阅读:
    小三学算术
    The Balance
    扫描线
    2019牛客暑期多校训练营(第九场)
    后缀数组
    Manacher
    局部变量和全局变量的区别
    2386:Lake Counting-poj
    简单背包问题(0032)-swust oj
    编程中易犯错误集锦-持续更新。。。。。
  • 原文地址:https://www.cnblogs.com/arbitrary/p/2941200.html
Copyright © 2020-2023  润新知