SGU-106 A equação (Europa expandida + processamento detalhado)

Portal


Tema

给出ax + por + c = 0 ax + por + c = 0a x+b y+c=0 é uma equação binária indefinida de um grau, e é satisfeito que{(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 ] } O número de soluções.

Ideias para resolução de problemas

Achei que tinha escrito muitas perguntas sobre a expansão da Europa e sabia bem disso, mas essa pergunta me atingiu de novo, wa wa waw um a duvidar de vida ...

Em primeiro lugar, não é difícil pensar se ccc movido para o lado direito da equação ainda é negativo, entãoccdeve serc muda de sinal, ao mesmo tempoa, ba, ba ,b também deve mudar de sinal, mas neste momentoa, ba, ba ,O sinal de b pode ser negativo. No início, minha ideia era fazer referência às variáveis ​​independentesx, yx, yx ,y , isto é,∣ a ∣ (- x) + ∣ b ∣ (- y) = c | a | (-x) + | b | (-y) = ca ( - x )+b ( - y )=c , e então tire o negativo diretamente após encontrar a solução especial. Não é possível fazer isso? Sim, mas não nesta pergunta. Os motivos são os seguintes:

Porque o que exigimos é o número de soluções em um determinado espaço de solução, suponha que não consideremos a, ba, ba ,O símbolo de b então a equação acima é convertida emx = c - byax = \ frac {c-by} {a}x=umac - b y, Este aauma mudança de pós-sinal afeta diretamente a forma final da solução geral é alterada, então se quisermosaauma negação, o caminho correto é dado pelo inverso do espaço da solução, ou seja, torna-se[- rx, - lx] [[ - r x ,- L x ] parayyy é o mesmo.

Depois de resolvermos a solução geral, precisamos obter o número de soluções, porque x, yx, yx ,A transformação de y é o oposto. Parece difícil começar, mas na verdade só precisamos resolver essa desigualdadelx ≤ x 0 + k 1 bgcd (a, b) ≤ rx lx \ leq x_0 + k_1 \ frac {b } {gcd (a, b)} \ leq rxl xx0+k1g c d ( a , b )br x encontrarxxx no espaço de soluçãok 1 k_1k1O intervalo de valores e, em seguida, yyy 'sk 2 k_2k2Para o intervalo de valores de, pegue apenas uma interseção dos dois. Neste momento, você precisa prestar atenção novamente. O lado esquerdo deve ser arredondado para cima e o lado direito deve ser arredondado para baixo. Faça um desenho para entender.

Há um julgamento especial a = 0, b = 0 a = 0, b = 0uma=0 ,b=Três 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;
}

Acho que você gosta

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