1. 程式人生 > >[lightoj P1306] Solutions to an Equation

[lightoj P1306] Solutions to an Equation

bit solution gif ons sam range else 把他 align

[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