解的个数(扩展欧几里得解不定方程)

解的个数

题目描述:
已知整数x,y满足如下面的条件:
ax+by+c = 0
p<=x<=q
r<=y<=s
求满足这些条件的x,y的个数。
输入描述:
第一行有一个整数n(n<=10),表示有n个任务。n<=10
以下有n行,每行有7个整数,分别为:a,b,c,p,q,r,s。均不超过108。
输出描述:
共n行,第i行是第i个任务的解的个数。
样例输入:
2
2 3 -7 0 10 0 10
1 1 1 -10 10 -9 9
样例输出:
1
19

#include<iostream>
#include<cstdio>
#define lon long long
using namespace std;
int t,x,y,g,ans;
int a,b,c,l1,l2,r1,r2;
int ex_gcd(int a,int b,int &x,int &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    int r=ex_gcd(b,a%b,x,y);
    int t=x;x=y;y=t-a/b*y;
    return r;
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        ans=0;
        scanf("%d%d%d%d%d%d%d",&a,&b,&c,&l1,&r1,&l2,&r2);
        c=-c;
        if(a==0&&b==0)
        {
            if(c!=0||l1>r1||l2>r1)
            {
                printf("0\n");
                continue;
            }
            long long t1=r1-l1+1,t2=r2-l2+1;
            long long t3=t1*t2;
            cout<<t3;
            printf("\n");
            continue;
        }
        if(a==0)
        {
            y=c/b;
            if(y<l2||y>r2||c%b!=0)
            printf("0\n");
            else printf("1\n");
            continue;
        }
        if(b==0)
        {
            x=c/a;
            if(x<l1||x>r1||c%a!=0)
            printf("0\n");
            else printf("1\n");
            continue;
        }
        g=ex_gcd(a,b,x,y);
        if(c%g!=0)
        {
            printf("0\n");
            continue;
        }
        int s=c/g;
        x=x*s,y=y*s;
        int ta=a/g,tb=b/g;
        if(x<l1)
        {
            while(x<l1) x+=tb,y-=ta;
            for(int i=x;i<=r1;i+=tb,y-=ta)
            if(y>=l2&&y<=r2) ans++;
        }
        else if(x>r1)
        {
            while(x>r1) x-=tb,y+=ta;
            for(int i=x;i>=l1;i-=tb,y+=ta)
            if(y>=l2&&y<=r2) ans++;
        }
        else
        {
            int ty=y;
            for(int i=x;i<=r1;i+=tb,ty-=ta)
            if(ty>=l2&&ty<=r2) ans++;
            ty=y+ta;
            for(int i=x-tb;i>=l1;i-=tb,ty+=ta)
            if(ty>=l2&&ty<=r2) ans++;
        }
        cout<<ans; printf("\n");
    }
    return 0;
}
posted @ 2016-11-12 19:34  抽空的太阳  阅读(278)  评论(0编辑  收藏  举报