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的逆元。