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

[lightoj P1306] Solutions to an Equation

时间:2017-10-26 22:44:59      阅读:219      评论:0      收藏:0      [点我收藏+]

标签:++   div   view   san   eve   its   c++   style   分类   

[lightoj P1306] Solutions to an Equation

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

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

Sample Output

Case 1: 3

Case 2: 37

Case 3: 1

Case 4: 2

Case 5: 1

 

毒瘤题。。。

首先肯定要用到exgcd。。都快忘了。

再推一下——

     Ax0+By0=gcd(A,B)

=  Bx+(A%B)y=gcd(B,A%B)

=  Bx+(A-(A/B)*B)y

=  Ay+B(x-(A/B)y)

则 x0=y,y0=(x-(A/B)y)。

好,推好式子再回到题目。

为了省去一些复杂的分类讨论,我们把A,B都搞成非负整数,同事区间范围也要改动。

然后判断几个特殊情况:

A==0&&B==0——>ans=(rx-lx+1)*(ry-ly+1)*(C==0)

A==0——>ans=(rx-lx+1)*jug(C/B in [ly..ry])*(C%B==0)

B==0——>ans=(ry-ly+1)*jug(C/A in [lx..rx])*(C%A==0)

然后,就是一般情况。

我们知道,AB同号时,x增加时,y减少,x减少时y增加。

我们设在做exgcd的时候得到的一组解为X,Y。

那么,如果X<lx||Y>ry,那么,我们要把他们都移进合法区间内。然后得到最极端的解。然后算出另一边的极端解,然后处理一下细节。

如果X>rx||Y<ly,也差不多。

如果原来X,Y就都在合法范围内,我们可以先把某一个处理得不合法,再做上面的工作。

具体怎么算极端解,我真的没法讲清楚,细节非常多。。

还有这种题要尽量避免分类讨论。。

code:

技术分享
 1 #include<bits/stdc++.h>
 2 #define LL long long
 3 using namespace std;
 4 LL A,B,C,lx,rx,ly,ry,X,Y,gcd,delx,dely;
 5 LL sx,sy,tx,ty,del,x[2],y[2],ans,kx,ky,k;
 6 LL exgcd(LL A,LL B,LL &x,LL &y) {
 7     if (!B) {x=1; y=0; return A;}
 8     LL g=exgcd(B,A%B,x,y);
 9     LL x0=y,y0=x-y*(A/B);
10     x=x0; y=y0; return g;
11 }
12 bool range_xy(LL x,LL y) {return x>=lx&&x<=rx&&y>=ly&&y<=ry;}
13 int main() {
14     int T; cin>>T;
15     for (int ts=1; ts<=T; ts++) {
16         scanf("%lld%lld%lld",&A,&B,&C);
17         scanf("%lld%lld%lld%lld",&lx,&rx,&ly,&ry);
18         
19         if (A<0) A=-A,lx=-lx,rx=-rx,swap(lx,rx);
20         if (B<0) B=-B,ly=-ly,ry=-ry,swap(ly,ry);
21         C=-C;
22         if (A==0&&B==0) {
23             printf("Case %d: %lld\n",ts,(rx-lx+1)*(ry-ly+1)*(C==0)); continue;
24         }
25         
26         gcd=exgcd(A,B,X,Y);
27         if (C%gcd!=0) {printf("Case %d: %lld\n",ts,0); continue;}
28         X=X*C/gcd,Y=Y*C/gcd;
29         delx=B/gcd,dely=A/gcd,ans=0;
30         
31         if (delx==0) {
32             if (C%A!=0) ans=0; else sx=C/A,ans=(ry-ly+1)*range_xy(sx,ly);
33             printf("Case %d: %lld\n",ts,ans); continue;
34         }else
35         if (dely==0) {
36             if (C%B!=0) ans=0; else sy=C/B,ans=(rx-lx+1)*range_xy(lx,sy);
37             printf("Case %d: %lld\n",ts,ans); continue;
38         }
39         
40         sx=X,sy=Y;
41         if (sx>=lx) {
42             k=(sx-lx)/delx+1;
43             sx=sx-k*delx,sy=sy+k*dely;
44         }
45         if (sx<lx||sy>ry) {
46             if ((lx-sx)%delx==0) kx=(lx-sx)/delx; else kx=(lx-sx)/delx+1;
47             if ((sy-ry)%dely==0) ky=(sy-ry)/dely; else ky=(sy-ry)/dely+1;
48             k=max(kx,ky);
49             sx+=delx*k,sy-=dely*k;
50             if (sx>rx||sy<ly) ans=0;
51             else {
52                 kx=(rx-sx)/delx;
53                 ky=(sy-ly)/dely;
54                 k=min(kx,ky);
55                 tx=sx+k*delx,ty=sy-k*dely;
56                 ans=min((tx-sx)/delx+1,(sy-ty)/dely+1);
57             }
58         }else
59         if (sx>rx||sy<ly) {
60             if ((sx-rx)%delx==0) kx=(sx-rx)/delx; else kx=(sx-rx)/delx+1;
61             if ((ly-sy)%dely==0) ky=(ly-sy)/dely; else ky=(ly-sy)/dely+1;
62             k=max(kx,ky);
63             sx-=delx*k,sy+=dely*k;
64             if (sx<lx||sy>ry) ans=0;
65             else{
66                 kx=(sx-lx)/delx;
67                 ky=(ry-sy)/dely;
68                 k=min(kx,ky);
69                 tx=sx-k*delx,ty=sy+k*dely;
70                 ans=min((sx-tx)/delx+1,(ty-sy)/dely+1);
71             }
72         }else if (!range_xy) ans=0;
73         printf("Case %d: %lld\n",ts,ans);
74     }
75     return 0;
76 }
View Code

 

[lightoj P1306] Solutions to an Equation

标签:++   div   view   san   eve   its   c++   style   分类   

原文地址:http://www.cnblogs.com/whc200305/p/7739236.html

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