La ecuación SGU - 106

enlaces a los temas: https://codeforces.com/problemsets/acmsguru/problem/99999/106

Este problema es particularmente bueno EXGCD sobre un tema. Efecto Título: Una ecuación de la número entero de soluciones de la ecuación ax + by + c = 0, las entradas a, b, c y una gama de L1, R1 y el intervalo b, L2, R2, salida cumple.

solución:

  ax + by + c = 0. Esta ecuación, considerar en primer lugar las circunstancias especiales:

1, a = 0 && b = 0 y c = 0, x e y son cualquier encuentran, por lo que la respuesta a (r1-l1 + 1) * (r2-L2 + 1)

2, a = 0 && b = 0, la salida directa 0

3, a = 0, la ecuación se convierte por = -c, c se determina si el múltiple b no es 0, entonces la salida directamente. A continuación se determina en un intervalo de y, si (L2, R2), la respuesta es (r1-l1 + 1) b = 0 de manera similar.

4, ax + by = -c. Trate de hacer que a y b son mayores que 0. Si a <0, entonces se convertirá en una, entonces un cambio positivo en el rango de igual a, b, probablemente sobre el mismo. C se moverá sobre, y para tratar de asegurar mayor que o igual a 0 -c

5, ax + by = c, resuelto con exgcd. En primer lugar, si c no es un múltiplo de gcd (a, b), y no hay solución. De lo contrario, convertir ecuación a1x + B1Y = c1. a1 = a / gcd (a, b), b, c empatía. X puede ser determinada por exgcd Solución Solución Set conjunto para kb x0 +, y es y0-ka. Luego la búsqueda de intervalo de acuerdo con la gama de k.

6, utilizaremos dos funciones ceil piso y cuando se evaluó gama. En donde piso representa un número entero de redondeo hasta el máximo (entero más grande menor que 4,9), ceil está abajo redondeado, 3,1 --- 4 es mayor que 3,1 si 4,9--4. Luego tomar un pequeño límite superior, el límite inferior puede tener grandes.

código:

#include <iostream> 
#include <cstdio> 
#include <cmath> 
#include <algoritmo>
 usando  espacio de nombres std; 
typedef largo  largo ll; 
mcd LL (ll a, II b) { 
    retorno b == 0 ? a: gcd (b, a% b); 
} 
Ll exgcd (ll a, ll b, ll y x, ll y y) {
     si (b == 0 ) { 
        x = 1 , y = 0 ;
        volver a; 
    } 
    Ll d = exgcd (b, a% b, y, x); 
    y - = a / b *X;
    volver d; 
} 
Int main () 
{ 
    ll a, b, c; 
    cin >> a >> b >> c; 
    c = - c; 
    ll L1, R1, L2, R2; 
    cin >> >> L1 L2 R1 >> >> r2;
    si (c < 0 ) { 
        c = -c; a = -a; b = - b; 
    } 
    Si (a < 0 ) { 
        a = -a; l1 = -L1; r1 = - R1; de intercambio (L1, R1); 
    } 
    Si (b < 0 ) { 
        b = -b; r2 = -R2; L2 = -  L2; swap (R2, L2);
    } 
    si(a == 0 && b == 0 && c == 0 ) { 
        cout << (r1 - l1 + 1 ) * (r2 - L2 + 1 ) << endl;
        volver  0 ; 
    } 
    Demás  si (a == 0 && b == 0 ) {cout << 0 << endl; volver  0 ; }
     Demás  si (b == 0 ) {
         si (c% b == 0 && (-c) / b <= r2 && (-c) / b> = L2) cout << r1 - l1 + 1 << endl ;
        otro tribunal << 0 << endl;
        volver  0 ; 
    } 
    Demás  si (a == 0 ) {
         si (c% a == 0 && -c) / a <= r1 && (-c) / a> = l1 () cout << r2 - L2 + 1 << endl ;
        otro tribunal << 0 << endl;
        volver  0 ; 
    } 
    Ll d = gcd (a, b);
    si (c% d =! 0 ) puts ( " 0 " );
    
        c = -c; 
        a / = d; b / = d; c / = d; 
        exgcd (a, b, x, y); 
        x = x * c; y = y * c;
//         cout << un << "-" << b << "==" << c << "-" << d << "===" << x << "-" < <y << endl; 
        doble RR1, LL1, RR2, LL2; 
        RR1 = doble (r1); LL1 = doble (L1); 
        RR2 = doble (r2); LL2 = doble (L2); 
        ll upx = floor ((RR1-x) / b), downx = ceil ((LL1-x) / b); 
        ll UPY = floor ((y-LL2) / a), downy = ceil ((Y-RR2) / a); << (American National Standard < 0 ? 0 : ans) << endl; 
    } 
    Volver  0 ; 
}

Complementario Exgcd (int a, int b, int & x, int & y) conocimiento:

Demostrar: ax + by = gcd (a, b) k. Calcula en primer lugar ax + by = gcd (a, b), se puede resolver y luego en k.

        bx + (a% b) y = mcd (b, a% b).

   a% b = a- (a / b) * b (donde a excepción de la división entera)

 Entra en el bx abierto + AY- (a / b) * por = mcd (b, a% b) = gcd (a, b) = ax + by, y luego el correspondiente equivalente, x = y, y = x- ( a / b) * b * y

El conjunto solución se determina x: x0 + kb, y: y0-ka

exgcd código:

void exgcd(int a,int b,int &x,int &y){
    if(b==0) {x=1,y=0}
    else {
        exgcd(a,b,x,y);
        int t=x;
        x=y;y=t-a/b*y;
    }
}

Exgcd还可以用来求解逆元。证明过程用到了同余方程即ax%b=c,也可记为ax=c(modb)当c等与1时,x就是a的逆元。

求解过程:ax-b*y=1,带入exgcd中,x就是a的逆元。

 

Supongo que te gusta

Origin www.cnblogs.com/Accepting/p/12581918.html
Recomendado
Clasificación