2012年10月18日 星期四

SGU 106 The equation

Be very careful to the boundary like a = 0 or b = 0 or (a = 0 and b = 0)

And be careful if there's no answer   ->   c % gcd(a, b) != 0

If answer exist, then:

ax+by+c = 0   ->   (-c-by) = 0 (mod a)   ->   y = -c*b^(-1) (mod a)

You can find one of the answer for y, 

Also you know the boundary of y, which is y = (y1~y2) & y = (-a * x1 - c) / b ~ (-a * x2 - c) / b

Then you can find out the answer. Mind that maybe both of them are negative so you need some ifs.

要做許許多多的特別判斷,才可以保證AC

//By momo
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;

LL a, b, c, x1, x2, y1, y2, ans;

bool bound(){
    if(a == 0 && b == 0){
        if(c == 0) ans = (x2 - x1 + 1)*(y2 - y1 + 1);
        return 0;
    }
    if(a == 0){
        if(c % a == 0 && c / b >= y1 && c / b <= y2) ans = x2 - x1 + 1;
        return 0;
    }
    if(b == 0){
        if(c % a == 0 && c / a >= x1 && c / a <= x2) ans = y2 - y1 + 1;
        return 0;
    }
    
    LL gcd = __gcd(a, b);
    if(c % gcd != 0) return 0;
    
    a /= gcd, b /= gcd, c /= gcd;
    return 1;
}

LL inv(LL x, LL y, LL p, LL q, LL r, LL s){
    if(y == 0) return p;
    return inv(y, x%y, r, s, p - (x/y)*r, q - (x/y)*s);
}

int main(){
    cin >> a >> b >> c >> x1 >> x2 >> y1 >> y2; c = -c;
    if(bound()){
        
        if(a < 0) a = -a, b = -b, c = -c;
        LL y = c*inv(b, a, 1, 0, 0, 1);
        LL l = (c-a*x1)/b, r = (c-a*x2)/b;
        if(l > r) swap(l, r);
        
        y1 = (max(y1, l)-y), y2 = (min(y2, r)-y);
        if(y1 <= y2){
            LL p = abs(y1) / a;
            LL q = abs(y2) / a;
            if(y1 > 0 && y2 > 0) ans = q - p + (y1 % a == 0);
            else if(y1 < 0 && y2 < 0) ans = p - q + (y2 % a == 0);
            else ans = p + q + 1;
        }

    }
    cout << ans << endl;
}

沒有留言:

張貼留言