SGU-106 La ecuación (Europa ampliada + procesamiento detallado)

Portal


Tema

给出ax + por + c = 0 ax + por + c = 0una x+b y+C=0 es una ecuación binaria indefinida de primer grado, que satisface{(x, y) ∣ x ∈ [lx, rx], y ∈ [ly, ry]} \ {(x, y) | x \ in [lx, rx] , y \ in [ly, ry] \}{ ( x ,y)x[ l x ,r x ] ,y[ l y ,r y ] } El número de soluciones.

Ideas para resolver problemas

Pensé que había escrito muchas preguntas sobre la expansión de Europa y lo sabía bien, pero esta pregunta volvió a golpearme en la cara, wa waw una a dudar de la vida ...

En primer lugar, no es difícil pensar que si ccc movido al lado derecho de la ecuación sigue siendo negativo, por lo queccdebe serc cambia de signo, al mismo tiempoa, ba, buna ,b también debería cambiar de signo, pero en este momentoa, ba, buna ,El signo de b puede ser negativo. Al principio mi idea era referirme a las variables independientesx, yx, yx ,y , es decir,∣ a ∣ (- x) + ∣ b ∣ (- y) = c | a | (-x) + | b | (-y) = ca ( - x )+b(y)=c , y luego tome el negativo directamente después de encontrar la solución especial. ¿No es posible hacer esto? Sí, pero no en esta pregunta. Los motivos son los siguientes:

Debido a que lo que necesitamos es el número de soluciones en un espacio de solución dado, suponga que no consideramos a, ba, buna ,El símbolo de b , entonces la ecuación anterior se convierte ax = c - byax = \ frac {c-by} {a}X=unac - b y, Esto aaun cambio de señal posterior afecta directamente a la forma final de la solución general se cambia, por lo que si queremosaauna negación, la forma correcta viene dada por el inverso del espacio solución, es decir, se convierte en[- rx, - lx] [[ - r x ,- L x ] parayyy es el mismo.

Luego, después de resolver la solución general, necesitamos obtener el número de soluciones, porque x, yx, yx ,La transformación de y es la opuesta. Parece difícil comenzar, pero de hecho, solo necesitamos resolver esta desigualdadlx ≤ x 0 + k 1 bgcd (a, b) ≤ rx lx \ leq x_0 + k_1 \ frac {b } {mcd (a, b)} \ leq rxl xX0+k1g c d ( a , b )br x encuentraxxx en el espacio soluciónk 1 k_1k1El rango de valores, y luego yyy 'sk 2 k_2k2Para el rango de valores de, simplemente tome una intersección de los dos. En este momento, debe prestar atención nuevamente. El lado izquierdo debe estar redondeado hacia arriba y el lado derecho debe estar redondeado hacia abajo. Haga un dibujo para comprender.

Hay un juicio especial a = 0, b = 0 a = 0, b = 0una=0 ,segundo=Tres casos de 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;
}

Supongo que te gusta

Origin blog.csdn.net/qq_44691917/article/details/109411788
Recomendado
Clasificación