SGU-106 The equation (Expanded Europe + detailed processing)

Portal


Topic

给出 a x + b y + c = 0 ax+by+c=0 ax+by+c=0 is a binary indefinite equation of the first degree, which satisfies{(x, y) ∣ x ∈ [lx, rx], y ∈ [ly, ry]} \{(x,y) | x \in [lx,rx] ,y\in [ly,ry]\}{ (x,y ) x[lx,rx],Y[ly,r y ] } The number of solutions.

Problem solving ideas

I thought I had written a lot of questions about expanding Europe and I knew it well, but this question hit my face again, wa waw a to doubt life...

First of all, it is not difficult to think that if ccc moved to the right side of the equation is still negative, soccshould bec changes sign, at the same timea, ba, ba,b should also change sign, but at this timea, ba, ba,The sign of b may be negative. At the beginning, my idea was to refer to the independent variablesx, yx, yx,y , that is,∣ a ∣ (− x) + ∣ b ∣ (− y) = c |a|(-x)+|b|(-y)=ca(x)+b ( - y )=c , and then take the negative directly after finding the special solution. Isn't it possible to do this? Yes, but not in this question. The reasons are as follows:

Because what we require is the number of solutions in a given solution space, suppose we don’t consider a, ba, ba,the symbol of b , then the above equation is converted tox = c − byax = \frac{c-by}{a}x=acby, This aaa post sign change directly affects the final form of the general solution is changed, so if we want toaaa negation, the correct way is given by the inverse of the solution space, i.e. becomes[- rx, - lx] [[rx,L x ] foryyy is the same.

Then after we solve the general solution, we need to get the number of solutions, because x, yx, yx,The transformation of y is the opposite. It seems difficult to start, but in fact we only need to solve this inequalitylx ≤ x 0 + k 1 bgcd (a, b) ≤ rx lx \leq x_0+k_1\frac{b }{gcd(a,b)} \leq rxlxx0+k1gcd(a,b)br x findxxx in the solution spacek 1 k_1k1The range of values, and then yyy 'sk 2 k_2k2For the value range of, just take one intersection of the two. At this time, you need to pay attention again. The left side should be rounded up, and the right side should be rounded down. Draw a picture to understand.

There is a special judgment a = 0, b = 0 a=0, b=0a=0,b=Three cases of 0


//
// Created by Happig on 2020/10/30
//
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>

using namespace std;
#define fi first
#define se second
#define pb push_back
#define ins insert
#define Vector Point
#define ENDL "\n"
#define lowbit(x) (x&(-x))
#define mkp(x, y) make_pair(x,y)
#define mem(a, x) memset(a,x,sizeof a);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
const double eps = 1e-8;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double dinf = 1e300;
const ll INF = 1e18;
const int Mod = 1e9 + 7;
const int maxn = 2e5 + 10;

ll exgcd(ll a, ll b, ll &x, ll &y) {
    
    
    if (!b) {
    
    
        x = 1, y = 0;
        return a;
    }
    ll d = exgcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
}

ll gcd(ll a, ll b) {
    
    
    return b == 0 ? a : gcd(b, a % b);
}

int main() {
    
    
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    //ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    ll a, b, c, lx, rx, ly, ry;
    cin >> a >> b >> c >> lx >> rx >> ly >> ry;
    c = -c;
    if (c < 0) c = -c, a = -a, b = -b;
    if (a < 0) a = -a, swap(lx, rx), lx = -lx, rx = -rx;
    if (b < 0) b = -b, swap(ly, ry), ly = -ly, ry = -ry;
    if (a == 0 && b == 0) {
    
    
        if (c == 0) cout << (rx - lx + 1) * (ry - ly + 1) << endl;
        else cout << 0 << endl;
        return 0;
    } else if (a == 0) {
    
    
        if (c % b == 0 && ly <= c / b && c / b <= ry) cout << rx - lx + 1 << endl;
        else cout << 0 << endl;
        return 0;
    } else if (b == 0) {
    
    
        if (c % a == 0 && lx <= c / a && c / a <= rx) cout << ry - ly + 1 << endl;
        else cout << 0 << endl;
        return 0;
    }
    ll d = gcd(a, b);
    if (c % d) {
    
    
        cout << "0" << endl;
    } else {
    
    
        ll x, y;
        exgcd(a, b, x, y);
        x = x * c / d, y = y * c / d;
        //cout << x << " " << y << endl;
        a /= d, b /= d;
        int l = max(ceil(1.0 * (lx - x) / b), ceil(1.0 * (y - ry) / a)), r = min(floor(1.0 * (rx - x) / b),
                                                                                 floor(1.0 * (y - ly) / a));
        if (r >= l) cout << r - l + 1 << endl;
        else cout << 0 << endl;
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/qq_44691917/article/details/109411788