light oj 1306

来源:互联网 发布:淘宝一件代发怎么操作 编辑:程序博客网 时间:2024/06/05 01:44

1306 - Solutions to an Equation
   PDF (English)StatisticsForum
Time Limit: 2 second(s)Memory Limit: 32 MB

You have to find the number of solutions of the following equation:

Ax + By + C = 0

Where A, B, C, x, y are integers and x1 ≤ x ≤ x2 and y1 ≤ y ≤ y2.

Input

Input starts with an integer T (≤ 10000), denoting the number of test cases.

Each case starts with a line containing seven integers A, B, C, x1, x2, y1, y2 (x1 ≤ x2, y1 ≤ y2). The value of each integer will lie in the range [-108, 108].

Output

For each case, print the case number and the total number of solutions.

Sample Input

Output for Sample Input

5

1 1 -5 -5 10 2 4

-10 -8 80 -100 100 -90 90

2 3 -4 1 7 0 8

-2 -3 6 -2 5 -10 5

1 8 -32 0 0 1 10

Case 1: 3

Case 2: 37

Case 3: 1

Case 4: 2

Case 5: 1



首先我们可以求出ax+by=gcd(a,b)=g的一个组解(x0,y0).而要使ax+by=c有解,必须有c%g==0.
继而可以得到ax+by=c的一个组解x1=c*x0/g , y1=c*y0/g。
这样可以得到ax+by=c的通解为: x=x1+b*t;y=y1-a*t;


#include <algorithm>#include <string.h>#include <iostream>#include <stdio.h>#include <string>#include <vector>#include <queue>#include <map>#include <set>using namespace std;typedef long long LL;const int N = 1e5+10;LL mint(LL x,LL y){    return x<=y?x:y;}LL maxt(LL x,LL y){    return x>=y?x:y;}LL exgcd(LL a,LL b,LL &x,LL &y){    if(b==0)    {        x=1, y=0;        return a;    }    LL ans=exgcd(b,a%b,x,y);    LL tmp=x;    x=y;    y=tmp-a/b*y;    return ans;}LL abs1(LL a){    return a>=0?a:-a;}LL F(LL x){    if(x==0) return 0;    if(x>0) return 1;    else return -1;}int main(){    int t, ncase=1;    scanf("%d", &t);    while(t--)    {        LL a, b, c, ax1,ax2, ay1, ay2;        scanf("%lld %lld %lld %lld %lld %lld %lld", &a, &b, &c, &ax1, &ax2, &ay1, &ay2);        printf("Case %d: ",ncase++);        if(a==0&&b==0)        {            if(c==0) printf("%lld\n",(ay2-ay1+1)*(ax2-ax1+1));            else printf("0\n");            continue;        }        else if(a==0)        {            if(c%b!=0) printf("0\n");            else            {                LL z=-c/b;                if(z>=ay1&&z<=ay2) printf("%lld\n",(ax2-ax1+1));                else printf("0\n");            }            continue;        }        else if(b==0)        {            LL z=-c/a;            if(c%a!=0) printf("0\n");            else if(z>=ax1&&z<=ax2) printf("%lld\n",(ay2-ay1+1));            else printf("0\n");            continue;        }        LL x, y;        LL g=exgcd(a,b,x,y);        if(c%g!=0) printf("0\n");        else//加和减没有区别因为都可以改变k的值得到,注意处理不等式乘以负数的符号变换,公式中的b为b/gcd(a,b)因为这样可以扩大k值        {            LL k1, k2, k3, k4;            if(b*g<0) swap(ax1,ax2);            k1=(ax1*g+c*x)/b;            if((ax1*g+c*x)% b!=0 && F(ax1*g+c*x)*F(b) > 0) k1+=1;            k2=(ax2*g+c*x)/b;            if((ax2*g+c*x)% (b)!=0 && F(ax2*g+c*x)*F(b) < 0) k2-=1;            if(-a*g<0) swap(ay1,ay2);            k3=(ay1*g+c*y)/(-a);            if((ay1*g+c*y)%(-a)!=0 && F(ay1*g+c*y)*F(-a)>0) k3+=1;            k4=(ay2*g+c*y)/(-a);            if((ay2*g+c*y)%(-a)!=0 && F(ay2*g+c*y)*F(-a)<0) k4-=1;            if(k3>k2||k4<k1) printf("0\n");            else printf("%lld\n",mint(k2,k4)-maxt(k1,k3)+1);        }    }    return 0;}

0 0