codevs 1213 解的个数

题目描述 Description

已知整数x,y满足如下面的条件:

 

ax+by+c = 0

p<=x<=q

r<=y<=s

 

求满足这些条件的x,y的个数。

输入描述 Input Description

第一行有一个整数nn<=10),表示有n个任务。n<=10

以下有n行,每行有7个整数,分别为:a,b,c,p,q,r,s。均不超过108。

输出描述 Output Description

n行,第i行是第i个任务的解的个数。

样例输入 Sample Input

2

2 3 -7 0 10 0 10

1 1 1 -10 10 -9 9

样例输出 Sample Output

1

19

思路:

扩展欧几里得,特判是一次函数的情况。

代码:

#include<cstdio>
#include<algorithm>
#include<iostream>
#define ll long long
using namespace std;
ll n,a,b,c,p,q,r,s,ans;
void exgcd(ll a,ll b,ll &x,ll &y)
{
    if(!b)
    {
        x=1;
        y=0;
        return ;
    }
    exgcd(b,a%b,y,x);
    y-=x*(a/b);
}
void slove()
{
    int t=__gcd(a,b);
    c*=-1;
    if(!a&&!b)
    {
        if(c||p>q||r>s)
          printf("0\n");
        else
          printf("%lld\n",(q-p+1)*(s-r+1));
        return ;
    }
    if(!a)
    {
        ll d=c/b;
        if(d>=r&&d<=s&&!(c%b))
          printf("1\n");
        else
          printf("0\n");
        return ;
    }
    if(!b)
    {
        ll d=c/a;
        if(d>=p&&d<=q&&!(c%a))
          printf("1\n");
        else
          printf("0\n");
        return ;
    }
    if(c%t)
    {
        printf("0\n");
        return ;
    }
    ll x=0,y=0;
    ans=0;
    exgcd(a,b,x,y);
    x=x*c/t;
    y=y*c/t;
    a/=t,b/=t;
    int e=0;
    if(x<p)
    {
        while(x+e*b<p) 
          e++;
        while(x+e*b<q)
        {
            if(r<=y-e*a&&y-e*a<=s) 
              ans++;
            e++;
        }
    }
    else 
      if(x>q)
      {
              while(x-e*b>q) 
                e++;
              while(x-e*b>p)
              {
                  if(r<=y+e*a&&y+e*a<=s)
                    ans++;
                  e++;
              }
      }
      else 
        if(x>=p&&x<=q)
        {
            while(x+e*b<=q)
            {
                if(r<=y-e*a&&y-e*a<=s) 
                  ans++;
                e++;
            }
            e=-1;
            while(x+e*b>=p)
            {
                if(r<=y-e*a&&y-e*a<=s) 
                  ans++;
                e--;
            }
        }
    printf("%lld\n",ans);
}
int main()
{
    int i,j;
    cin>>n;
    while(n--)
    {
        cin>>a>>b>>c>>p>>q>>r>>s;
        slove();
    }
    return 0;
}

 

posted @ 2016-11-11 20:31  一叶落尽天下秋  阅读(147)  评论(0编辑  收藏  举报