码迷,mamicode.com
首页 > 其他好文 > 详细

lightoj 1306 - Solutions to an Equation

时间:2015-05-23 18:26:41      阅读:105      评论:0      收藏:0      [点我收藏+]

标签:light oj   扩展欧几里得   数学   math   

扩展欧几里得

通解:x+B/GCD*k,y+A/GCD*k

先缩小x1,x2范围,再缩y

#include<bits/stdc++.h>
using namespace std;

void extgcd(long long a,long long b,long long &d,long long &x,long long &y)//return d=gcd(a,b)(==a*x+b*y)
{
    if(!b)
        d=a,x=1,y=0;
    else
    {
        extgcd(b,a%b,d,y,x);
        y-=x*(a/b);
    }
}
int main(void)
{
    //freopen("in","r",stdin);
    int t,Case=0;
    long long A,B,C,x1,x2,y1,y2;
    long long GCD,x,y;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lld%lld%lld%lld%lld%lld%lld",&A,&B,&C,&x1,&x2,&y1,&y2);
        printf("Case %d: ",++Case);
        if(A==0&&B==0)
        {
            if(C==0)
                printf("%lld\n",(x2-x1+1)*(y2-y1+1));
            else
                printf("0\n");
            continue;
        }
        if(A==0)
        {
            if(C%B!=0)
            {
                printf("0\n");
                continue;
            }
            y=-C/B;
            if(y1<=y&&y<=y2)
                printf("%lld\n",x2-x1+1);
            else
                printf("0\n");
            continue;
        }
        if(B==0)
        {
            if(C%A!=0)
            {
                printf("0\n");
                continue;
            }
            x=-C/A;
            if(x1<=x&&x<=x2)
                printf("%lld\n",y2-y1+1);
            else
                printf("0\n");
            continue;
        }
        extgcd(A,B,GCD,x,y);
        x*=-C/GCD;
        y*=-C/GCD;
        if(C%GCD!=0)
        {
            printf("0\n");
            continue;
        }
        long long base1=B/GCD;
        long long base2=A/GCD;
        long long l,r;
        x1=((x-x1)%base1+abs(base1))%abs(base1)+x1;
        x2=((x-x2)%base1-abs(base1))%abs(base1)+x2;
        if(x1>x2)
        {
            printf("0\n");
            continue;
        }
        l=(-base2)*((x1-x)/base1)+y;
        r=(-base2)*((x2-x)/base1)+y;
        if(l>r)
            swap(l,r);
        y1=max(y1,l);
        y2=min(y2,r);
        y1=((y-y1)%base2+abs(base2))%abs(base2)+y1;
        y2=((y-y2)%base2-abs(base2))%abs(base2)+y2;
        if(y1>y2)
            printf("0\n");
        else
            printf("%lld\n",(y2-y1)/abs(base2)+1);
    }
    return 0;
}


lightoj 1306 - Solutions to an Equation

标签:light oj   扩展欧几里得   数学   math   

原文地址:http://blog.csdn.net/loolu5/article/details/45935729

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!