├── logonotebook.png ├── Notebooks Compilados ├── c++ │ └── cpp.pdf └── java │ └── java.pdf ├── c++ ├── Math │ ├── Lowest Common Multiple.cpp │ ├── Greatest Common Divisor.cpp │ ├── Binomial Coefficient.cpp │ ├── Extended Euclides.cpp │ ├── Ternary Search.cpp │ ├── Sieve of Eratosthenes.cpp │ ├── Diophantine Ecuations.cpp │ ├── Mobius.cpp │ ├── Basis of a Vector Space (mod 2 Field).cpp │ ├── Miller Rabin.cpp │ ├── Euler Totient.cpp │ ├── Divisors.cpp │ ├── Pollard Rho.cpp │ ├── Simplex integer.cpp │ ├── Prime Factorization.cpp │ ├── Fast Fourier Transform.cpp │ ├── Fraction.cpp │ ├── Gauss Jordan.cpp │ └── Simplex.cpp ├── Modular arithmetic │ ├── Modular Multiplication.cpp │ ├── Fibonacci mod m.cpp │ ├── Modular Exponentiation.cpp │ ├── Chinese Remainder Theorem.cpp │ ├── Linear Recurrence.cpp │ ├── Discrete Logarithm.cpp │ ├── Pisano Period.cpp │ ├── Primitive Root.cpp │ ├── Matrix Multiplication.cpp │ └── Modular Inverse.cpp ├── Utilities │ ├── Random Integer.cpp │ ├── Split String.cpp │ ├── Template.cpp │ ├── scanf and printf.cpp │ └── Bits Manipulation.cpp ├── Dynamic programming │ ├── Max Range Sum.cpp │ ├── Min Max Range.cpp │ ├── Longest Increasing Subsequence.cpp │ └── Traveling Salesman Problem.cpp ├── Strings │ ├── Prefix Function.cpp │ ├── KMP.cpp │ ├── Z Function.cpp │ ├── KMP Automaton.cpp │ ├── Minimum Expression.cpp │ ├── Manacher.cpp │ ├── Palindromic tree.cpp │ ├── Hashing.cpp │ ├── Aho Corasick (Trie).cpp │ ├── Suffix Array.cpp │ └── Suffix Automaton.cpp ├── Graphs │ ├── Tree Isomorphism.cpp │ ├── Floyd Warshall.cpp │ ├── DFS.cpp │ ├── Cycle Detection.cpp │ ├── Flood Fill.cpp │ ├── Topological Sort.cpp │ ├── Kruskal.cpp │ ├── BFS.cpp │ ├── Bipartite Check.cpp │ ├── Tarjan.cpp │ ├── Prim.cpp │ ├── Bellman Ford.cpp │ ├── Dijkstra.cpp │ ├── 2-satisfiability.cpp │ ├── Lowest Common Ancestor.cpp │ └── Articulation Bridges Biconnected.cpp ├── Data structures │ ├── Min queue.cpp │ ├── Ordered Set.cpp │ ├── Sparse Table.cpp │ ├── Fenwick Tree.cpp │ ├── Disjoint Set.cpp │ ├── Persistent Segment Tree.cpp │ ├── Convex Hull Trick.cpp │ ├── Sparse table 2D.cpp │ ├── Dsu on Tree (Sack).cpp │ ├── Heavy Light Decomposition.cpp │ ├── Segment Tree 2D.cpp │ ├── Centroid Decomposition.cpp │ └── Segment Tree (Lazy Propagation).cpp ├── Values sequences and results │ ├── Time Complexities.tex │ ├── ASCII Table.tex │ └── Sequences.tex ├── Network flows │ ├── Hungarian.cpp │ ├── Dinic.cpp │ ├── Stoer Wagner.cpp │ ├── Maximum Bipartite Matching.cpp │ ├── Weighted matching.cpp │ ├── Blossom.cpp │ └── MinCost MaxFlow.cpp └── Geometry │ ├── line.cpp │ ├── segment.cpp │ ├── halfplanes.cpp │ ├── circle.cpp │ └── Point.cpp ├── java [outdated] ├── Math │ ├── Lowest Common multiple.java │ ├── Greatest common divisor.java │ ├── Catalan Number.java │ ├── Binomial Coefficient.java │ ├── Extended Euclides.java │ ├── Pollard Rho.java │ ├── Prime Factorization.java │ ├── Sieve of Eratosthenes.java │ ├── Mobius.java │ ├── Miller-Rabin.java │ ├── Euler Totient.java │ └── Gaussian Elimination.java ├── Geometry │ ├── Sexagesimal degrees and radians.java │ ├── Collinear Points.java │ ├── Gometric Vector.java │ ├── Perimeter.java │ ├── Angle.java │ ├── Point.java │ ├── Euclidean Distance.java │ ├── Area.java │ ├── Point in Polygon.java │ └── Convex Hull.java ├── Strings │ ├── Suffix Array strncmp.java │ ├── Suffix Array Longest Repeated Substring.java │ ├── Suffix Array Longest Common Prefix.java │ ├── Prefix Function.java │ ├── Z-Function.java │ ├── KMP's Algorithm.java │ ├── Suffix Array String Matching Boolean.java │ ├── Prefix-Function.java │ ├── Suffix Array Longest Common Substring.java │ ├── Suffix Array String Matching.java │ ├── String Hashing.java │ ├── Suffix Array Init.java │ └── Trie.java ├── Utilities │ ├── Biseccion.java │ ├── Binary search.java │ ├── Upper bound.java │ ├── Ternary Search.java │ ├── Lower bound.java │ ├── Bit Manipulation.java │ ├── Template.java │ └── Optimized Scanner.java ├── Modular arithmetic │ ├── Modular Exponentiation.java │ ├── Modular Multiplication.java │ ├── Fibonacci mod m.java │ ├── Chinese Remainder Theorem.java │ ├── Pisano Period.java │ └── Modular Inverse.java ├── Dynamic Programming │ ├── Max Range Sum.java │ ├── Min Max Range.java │ ├── Longest Common Subsequence.java │ ├── Longest increasing subsequence.java │ ├── Max Range 2D.java │ ├── Knapsack.java │ ├── Coin change.java │ ├── Max Range 3D.java │ └── Traveling Salesman Problem.java ├── Values sequences and results │ ├── Time Complexities.tex │ ├── ASCII Table.tex │ └── Sequences.tex ├── Graphs │ ├── Floyd Warshall.java │ ├── DFS.java │ ├── FloodFill.java │ ├── BFS.java │ ├── Topological Sort.java │ ├── Bipartite Check.java │ ├── LoopCheck.java │ ├── Tarjan.java │ ├── Kruskal.java │ ├── Prim.java │ ├── Puentes itmos.java │ ├── Dijkstra.java │ ├── Maxflow.java │ └── Lowest Common Ancestor.java └── Data Structures │ ├── Sparse Table.java │ ├── Fenwick Tree.java │ ├── Disjoint Set.java │ └── RMQ.java ├── LICENSE └── README.md /logonotebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ProgramacionCompetitivaUFPS/notebook/HEAD/logonotebook.png -------------------------------------------------------------------------------- /Notebooks Compilados/c++/cpp.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ProgramacionCompetitivaUFPS/notebook/HEAD/Notebooks Compilados/c++/cpp.pdf -------------------------------------------------------------------------------- /Notebooks Compilados/java/java.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ProgramacionCompetitivaUFPS/notebook/HEAD/Notebooks Compilados/java/java.pdf -------------------------------------------------------------------------------- /c++/Math/Lowest Common Multiple.cpp: -------------------------------------------------------------------------------- 1 | Calculo del minimo comun multiplo usando el maximo comun divisor. 2 | 3 | // O(log(max(a, b))) 4 | int lcm(int a, int b) { 5 | return a / __gcd(a, b) * b; 6 | } 7 | -------------------------------------------------------------------------------- /c++/Modular arithmetic/Modular Multiplication.cpp: -------------------------------------------------------------------------------- 1 | * Calcula (a*b) % m sin overflow cuando m es ll. 2 | // O(1) 3 | ll mulmod(ll a, ll b, ll m) { 4 | ll r = a*b-(ll)((long double)a*b/m+.5)*m; 5 | return r < 0 ? r+m : r; 6 | } 7 | -------------------------------------------------------------------------------- /java [outdated]/Math/Lowest Common multiple.java: -------------------------------------------------------------------------------- 1 | Calculo del mínimo común múltiplo usando el máximo común divisor. Agregar Greatest Common Divisor. 2 | 3 | public static int lcm(int a, int b) { 4 | return a * b / gcd(a, b); 5 | } 6 | -------------------------------------------------------------------------------- /c++/Math/Greatest Common Divisor.cpp: -------------------------------------------------------------------------------- 1 | Calcula el maximo comun divisor entre a y b mediante el algoritmo de Euclides. Tambien se puede usar __gcd(a, b). 2 | 3 | // O(log(max(a, b))) 4 | int gcd(int a, int b) { 5 | return b == 0 ? a : gcd(b, a%b); 6 | } 7 | -------------------------------------------------------------------------------- /java [outdated]/Math/Greatest common divisor.java: -------------------------------------------------------------------------------- 1 | Calcula el máximo común divisor entre a y b mediante el algoritmo de Euclides 2 | 3 | public static int gcd(int a, int b) { 4 | if (b == 0) { 5 | return a; 6 | } 7 | return gcd(b, a % b); 8 | } 9 | -------------------------------------------------------------------------------- /c++/Utilities/Random Integer.cpp: -------------------------------------------------------------------------------- 1 | Genera un numero entero aleatorio en el rango [a, b]. Para ll usar "mt19937_64" y cambiar todo a ll. 2 | 3 | mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); 4 | int rand(int a, int b) { return uniform_int_distribution(a, b)(rng); } 5 | -------------------------------------------------------------------------------- /java [outdated]/Geometry/Sexagesimal degrees and radians.java: -------------------------------------------------------------------------------- 1 | Conversiones de grados sexagesimales a radianes y viceversa. 2 | 3 | static double DegToRad(double d) { 4 | return d * Math.PI / 180.0; 5 | } 6 | 7 | static double RadToDeg(double r) { 8 | return r * 180.0 / Math.PI; 9 | } 10 | -------------------------------------------------------------------------------- /java [outdated]/Strings/Suffix Array strncmp.java: -------------------------------------------------------------------------------- 1 | Método utilitario. Necesario para las dos versiones de Matching. 2 | 3 | static int strncmp(char[] a, int i, char[] b) { 4 | for (int k = 0; i + k < a.length && k < m - 1; k++) { 5 | if (a[i + k] != b[k]) return a[i + k] - b[k]; 6 | } 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /java [outdated]/Utilities/Biseccion.java: -------------------------------------------------------------------------------- 1 | Método de bisección para una función f(m) 2 | 3 | static double eps = 0.0000001; 4 | 5 | static double bis(double a, double b) { 6 | double m = (a+b)/2; 7 | if (Math.abs(f(m)) < eps) return m; 8 | if (f(a) * f(m) < 0) return bis(a, m); 9 | return bis(m, b); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /java [outdated]/Math/Catalan Number.java: -------------------------------------------------------------------------------- 1 | Guarda en el array Catalan Numbers los numeros de Catalan hasta MAX. 2 | 3 | static int MAX = 30; 4 | static long catalan[] = new long[MAX+1]; 5 | 6 | static void catalanNumbers() { 7 | catalan[0] = 1; 8 | for (int i = 1; i <= MAX; i++) { 9 | catalan[i] = (long)(catalan[i-1]*((double)(2*((2 * i)- 1))/(i + 1))); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /java [outdated]/Geometry/Collinear Points.java: -------------------------------------------------------------------------------- 1 | Determina si el punto r está en la misma linea que los puntos p y q. IMPORTANTE: Deben incluirse las estructuras point y vec. 2 | 3 | static double cross(Vec a, Vec b) { 4 | return a.x * b.y - a.y * b.x; 5 | } 6 | 7 | static boolean collinear(Point p, Point q, Point r) { 8 | return Math.abs(cross(toVector(p, q), toVector(p, r))) < 1e-9; 9 | } 10 | -------------------------------------------------------------------------------- /java [outdated]/Modular arithmetic/Modular Exponentiation.java: -------------------------------------------------------------------------------- 1 | Realiza la operación (a ^ b) % mod. 2 | 3 | static long modpow(long a, long b, long mod) { 4 | if (b == 0) return 1; 5 | if (b % 2 == 0) { 6 | long temp = modpow(a, b/2, mod); 7 | return (temp * temp) % mod; 8 | } else { 9 | long temp = modpow(a, b-1, mod); 10 | return (temp * a) % mod; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /c++/Math/Binomial Coefficient.cpp: -------------------------------------------------------------------------------- 1 | Calcula el coeficiente binomial nCr, entendido como el numero de subconjuntos de r elementos escogidos de un conjunto con n elementos. 2 | 3 | // O(min(r, n-r)) 4 | ll ncr(ll n, ll r) { 5 | if (r < 0 || n < r) return 0; 6 | r = min(r, n-r); 7 | ll ans = 1; 8 | for (int i = 1; i <= r; i++) { 9 | ans = ans * (n-i+1) / i; 10 | } 11 | return ans; 12 | } 13 | -------------------------------------------------------------------------------- /c++/Math/Extended Euclides.cpp: -------------------------------------------------------------------------------- 1 | El algoritmo de Euclides extendido retorna el gcd(a, b) y calcula los coeficientes enteros X y Y que satisfacen la ecuacion: a*X + b*Y = gcd(a, b). 2 | 3 | int x, y; 4 | // O(log(max(a, b))) 5 | int euclid(int a, int b) { 6 | if (b == 0) { x = 1; y = 0; return a; } 7 | int d = euclid(b, a%b); 8 | int aux = x; 9 | x = y; 10 | y = aux - a/b*y; 11 | return d; 12 | } 13 | -------------------------------------------------------------------------------- /java [outdated]/Dynamic Programming/Max Range Sum.java: -------------------------------------------------------------------------------- 1 | Dado un arreglo de enteros, retorna la máxima suma de un rango de la lista. 2 | 3 | static int maxRangeSum(int[] a) { 4 | int sum = 0, ans = 0; 5 | for (int i = 0; i < a.length; i++) { 6 | if (sum + a[i] >= 0) { 7 | sum += a[i]; 8 | ans = Math.max(ans, sum); 9 | } else sum = 0; 10 | } 11 | return ans; 12 | } 13 | -------------------------------------------------------------------------------- /c++/Dynamic programming/Max Range Sum.cpp: -------------------------------------------------------------------------------- 1 | Dada una lista de enteros, retorna la máxima suma de un rango de la lista. 2 | 3 | #include 4 | 5 | int maxRangeSum(vector a) { 6 | int sum = 0, ans = 0; 7 | for (int i = 0; i < a.size(); i++) { 8 | if (sum + a[i] >= 0) { 9 | sum += a[i]; 10 | ans = max(ans, sum); 11 | } else sum = 0; 12 | } 13 | return ans; 14 | } 15 | -------------------------------------------------------------------------------- /java [outdated]/Math/Binomial Coefficient.java: -------------------------------------------------------------------------------- 1 | Calcula el coeficiente binomial nCr, entendido como el número de subconjuntos de k elementos escogidos de un conjunto con n elementos. 2 | 3 | static long ncr(long n, long r) { 4 | if (r < 0 || n < r) return 0; 5 | r = Math.min(r, n - r); 6 | long ans = 1; 7 | for (int i = 1; i <= r; i++) { 8 | ans = ans * (n - i + 1) / i; 9 | } 10 | return ans; 11 | } 12 | -------------------------------------------------------------------------------- /java [outdated]/Math/Extended Euclides.java: -------------------------------------------------------------------------------- 1 | El algoritmo de Euclides extendido retorna el gcd(a, b) y calcula los coeficientes enteros X y Y que satisfacen la ecuación: a*X + b*Y = gcd(a, b). 2 | 3 | static int x, y; 4 | // O(log(max(a, b))) 5 | int euclid(int a, int b) { 6 | if (b == 0) { x = 1; y = 0; return a; } 7 | int d = euclid(b, a % b); 8 | int aux = x; 9 | x = y; 10 | y = aux - ((a/b)*y); 11 | return d; 12 | } 13 | -------------------------------------------------------------------------------- /java [outdated]/Modular arithmetic/Modular Multiplication.java: -------------------------------------------------------------------------------- 1 | Realiza la operación (a * b) % mod minimizando posibles desbordamientos. 2 | 3 | public static long modmul(long a, long b, long mod) { 4 | long x = 0; 5 | long y = a % mod; 6 | while (b > 0) { 7 | if (b % 2 == 1) { 8 | x = (x + y) % mod; 9 | } 10 | y = (y << 1) % mod; 11 | b >>= 1; 12 | } 13 | return x % mod; 14 | } 15 | -------------------------------------------------------------------------------- /c++/Modular arithmetic/Fibonacci mod m.cpp: -------------------------------------------------------------------------------- 1 | Calcula fibonacci(n) % m. 2 | 3 | // O(log(n)) 4 | int fibmod(ll n, int m) { 5 | int a = 0, b = 1, c; 6 | for (int i = 63-__builtin_clzll(n); i >= 0; i--) { 7 | c = a; 8 | a = (1ll*c*(2ll*b-c+m)) % m; 9 | b = (1ll*c*c + 1ll*b*b) % m; 10 | if ((n>>i) & 1) { 11 | c = (a+b) % m; 12 | a = b; b = c; 13 | } 14 | } 15 | return a; 16 | } 17 | -------------------------------------------------------------------------------- /c++/Modular arithmetic/Modular Exponentiation.cpp: -------------------------------------------------------------------------------- 1 | * Calcula (b^e) % m (e puede ser ll). b debe estar ya con modulo m. 2 | Si m es ll se debe cambiar todo a ll, agregar Modular Multiplication y calcular las multiplicaciones con mulmod(). 3 | // O(log(e)) 4 | int expmod(int b, int e, int m) { 5 | int ans = 1; 6 | while (e) { 7 | if (e&1) ans = (1ll*ans*b) % m; 8 | b = (1ll*b*b) % m; 9 | e /= 2; 10 | } 11 | return ans; 12 | } 13 | -------------------------------------------------------------------------------- /java [outdated]/Utilities/Binary search.java: -------------------------------------------------------------------------------- 1 | Dado un arreglo ordenado ascendentemente de tamaño n, busca el elemento x y devuelve su posición, si no lo encuentra devuelve -1. 2 | 3 | static int binary_search(int array[], int x) { 4 | int l = 0, r = arr.length-1; 5 | while (l <= r) { 6 | int m = (l+r)/2; 7 | if (array[m] < x) l = m+1; 8 | else if (array[m] > x) r = m-1; 9 | else return m; 10 | } 11 | return -1; 12 | } 13 | -------------------------------------------------------------------------------- /c++/Utilities/Split String.cpp: -------------------------------------------------------------------------------- 1 | Divide el string s por cada espacio ' ' y devuelve un vector<> con los substrings resultantes. 2 | Para dividir el string por un caracter especifico, agregar el parametro c y cambiar el while. 3 | 4 | vector split(const string &s/*, char c*/) { 5 | vector v; 6 | stringstream ss(s); 7 | string sub; 8 | while (ss >> sub) v.pb(sub); 9 | // while (getline(ss, sub, c)) v.pb(sub); 10 | return v; 11 | } 12 | -------------------------------------------------------------------------------- /java [outdated]/Geometry/Gometric Vector.java: -------------------------------------------------------------------------------- 1 | Dados dos puntos A y B, crea el vector A->B. IMPORTANTE: Debe definirse la clase Point. Es llamado Vec para no confundirlo con vector como colección de elementos. 2 | 3 | static class Vec { 4 | public double x, y; 5 | public Vec(double _x, double _y) { 6 | this.x = _x; 7 | this.y = _y; 8 | } 9 | } 10 | 11 | static Vec toVector(Point a, Point b) { 12 | return new Vec(b.x - a.x, b.y - a.y); 13 | } 14 | -------------------------------------------------------------------------------- /c++/Math/Ternary Search.cpp: -------------------------------------------------------------------------------- 1 | Retorna el valor máximo de una función f(x) entre [l, r] 2 | 3 | const double eps = 1e-9; 4 | 5 | double ternary_search(double l, double r) { 6 | while (r - l > eps) { // O se pueden hacer unas 100 iteraciones 7 | double m1 = l + (r - l) / 3; 8 | double m2 = r - (r - l) / 3; 9 | double f1 = f(m1); 10 | double f2 = f(m2); 11 | if (f1 < f2) l = m1; 12 | else r = m2; 13 | } 14 | return f(l); 15 | } 16 | -------------------------------------------------------------------------------- /c++/Strings/Prefix Function.cpp: -------------------------------------------------------------------------------- 1 | Dado un string s retorna un vector pf donde pf[i] es el largo del prefijo propio mas largo que tambien es sufijo de s[0] hasta s[i]. 2 | 3 | // O(n) 4 | vector prefix_function(string &s) { 5 | int n = s.size(); 6 | vector pf(n); 7 | pf[0] = 0; 8 | for (int i = 1, j = 0; i < n; i++) { 9 | while (j && s[i] != s[j]) j = pf[j-1]; 10 | if (s[i] == s[j]) j++; 11 | pf[i] = j; 12 | } 13 | return pf; 14 | } 15 | -------------------------------------------------------------------------------- /c++/Utilities/Template.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define fastIO ios::sync_with_stdio(0), cin.tie(0) 4 | #define endl '\n' 5 | #define pb push_back 6 | typedef long long ll; 7 | typedef pair pii; 8 | 9 | int main() { 10 | fastIO; 11 | // Tu código... 12 | int a, b; 13 | cin >> a >> b; 14 | double c = a + b; 15 | // Para imprimir con 6 decimales 16 | // cout << fixed << setprecision(6); 17 | cout << c << endl; 18 | } 19 | -------------------------------------------------------------------------------- /java [outdated]/Geometry/Perimeter.java: -------------------------------------------------------------------------------- 1 | Calcula el perímetro de un polígono representado como un vector de puntos. IMPORTANTE: Definir P[0] = P[n-1] para cerrar el polígono. La estructura point debe estar definida, al igual que el método euclideanDistance. 2 | 3 | public static double perimeter(ArrayList P) { 4 | double result = 0.0; 5 | for (int i = 0; i < P.size()-1; i++) { 6 | result += euclideanDistance(P.get(i), P.get(i+1)); 7 | } 8 | return result; 9 | } 10 | -------------------------------------------------------------------------------- /java [outdated]/Utilities/Upper bound.java: -------------------------------------------------------------------------------- 1 | Dado un arreglo ordenado ascendentemente de tamaño n, busca el elemento x y devuelve la posición siguiente a la ultima aparición de x. Si la posición se sale del arreglo devuelve -1. 2 | 3 | static int upper_bound(int arr[], int x) { 4 | int l = 0, r = arr.length-1; 5 | if (arr[r] <= x) return -1; 6 | while (l < r) { 7 | int m = (l+r)/2; 8 | if (arr[m] <= x) l = m+1; 9 | else r = m; 10 | } 11 | return l; 12 | } 13 | -------------------------------------------------------------------------------- /c++/Math/Sieve of Eratosthenes.cpp: -------------------------------------------------------------------------------- 1 | Guarda en primes los numeros primos menores o iguales a MX. Para saber si p es un número primo, hacer: if (!marked[p]). 2 | 3 | const int MX = 1e6; 4 | bool marked[MX+1]; 5 | vector primes; 6 | // O(MX log(log(MX))) 7 | void sieve() { 8 | marked[0] = marked[1] = true; 9 | for (int i = 2; i <= MX; i++) { 10 | if (marked[i]) continue; 11 | primes.pb(i); 12 | for (ll j = 1ll*i*i; j <= MX; j += i) marked[j] = true; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /c++/Math/Diophantine Ecuations.cpp: -------------------------------------------------------------------------------- 1 | Encuentra x, y en la ecuación de la forma ax + by = c 2 | Agregar Extended Euclides. 3 | 4 | ll g; 5 | bool diophantine(ll a, ll b, ll c) { 6 | x = y = 0; 7 | if (!a && !b) return (!c); // sólo hay solución con c = 0 8 | g = euclid(abs(a), abs(b)); 9 | if (c % g) return false; 10 | a /= g; b /= g; c /= g; 11 | if (a < 0) x *= -1; 12 | x = (x % b) * (c % b) % b; 13 | if (x < 0) x += b; 14 | y = (c - a*x) / b; 15 | return true; 16 | } 17 | -------------------------------------------------------------------------------- /c++/Strings/KMP.cpp: -------------------------------------------------------------------------------- 1 | Cuenta las ocurrencias del string p en el string s. Agregar Prefix Function. 2 | 3 | // O(n+m) 4 | int kmp(string &s, string &p) { 5 | int n = s.size(), m = p.size(), cnt = 0; 6 | vector pf = prefix_function(p); 7 | for (int i = 0, j = 0; i < n; i++) { 8 | while (j && s[i] != p[j]) j = pf[j-1]; 9 | if (s[i] == p[j]) j++; 10 | if (j == m) { 11 | cnt++; 12 | j = pf[j-1]; 13 | } 14 | } 15 | return cnt; 16 | } 17 | -------------------------------------------------------------------------------- /java [outdated]/Geometry/Angle.java: -------------------------------------------------------------------------------- 1 | Dados 3 puntos A, B, y C, determina el valor del angulo ABC (origen en B) en radianes. IMPORTANTE: Definir la clase Point y Vec (Geometric Vector). Si se desea convertir a grados sexagesimales, revisar Sexagesimal degrees and radians. 2 | 3 | static double angle(Point a, Point b, Point c) { 4 | Vec ba = toVector(b, a); 5 | Vec bc = toVector(b, c); 6 | return Math.acos((ba.x * bc.x + ba.y * bc.y) / Math.sqrt((ba.x * ba.x + ba.y * ba.y) * (bc.x * bc.x + bc.y * bc.y))); 7 | } 8 | -------------------------------------------------------------------------------- /java [outdated]/Geometry/Point.java: -------------------------------------------------------------------------------- 1 | La clase punto será la base sobre la cual se ejecuten otros algoritmos. 2 | 3 | static class Point { 4 | public double x, y; 5 | public Point() { this.x = this.y = 0.0; } 6 | public Point(double _x, double _y) { 7 | this.x = _x; 8 | this.y = _y; 9 | } 10 | public boolean equals(Point other) { 11 | if (Math.abs(this.x - other.x) < 1e-9 && (Math.abs(this.y - other.y) < 1e-9)) return true; 12 | return false; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /java [outdated]/Strings/Suffix Array Longest Repeated Substring.java: -------------------------------------------------------------------------------- 1 | Retorna un int[] con el size y el indice del suffix array en el cual se encuentra el substring repetido mas largo. Debe ejecutarse primero suffixArray() y calculateLCP(). 2 | 3 | static int[] longestRepeatedSubstring() { 4 | int ans[] = new int[2]; ans[0] = -1; ans[1] = -1; 5 | for (int i = 0; i < n; i++) { 6 | if (ans[0] < lcp[i]) { 7 | ans[0] = lcp[i]; ans[1] = i; 8 | } 9 | } 10 | return ans; 11 | } 12 | -------------------------------------------------------------------------------- /java [outdated]/Utilities/Ternary Search.java: -------------------------------------------------------------------------------- 1 | Retorna el valor minimo de una funcion entre l y r. Se recomienda usar 50 iteraciones. 2 | 3 | static double f(double x) { 4 | return // funcion a evaluar que depende de x 5 | } 6 | 7 | static double ternary_search(double l, double r, int it) { 8 | double a = (2.0*l + r)/3.0; 9 | double b = (l + 2.0*r)/3.0; 10 | if (it == 0) return f(a); 11 | if (f(a) < f(b)) return ternary_search(l, b, it-1); 12 | return ternary_search(a, r, it-1); 13 | } 14 | -------------------------------------------------------------------------------- /c++/Strings/Z Function.cpp: -------------------------------------------------------------------------------- 1 | Dado un string s retorna un vector z donde z[i] es igual al mayor numero de caracteres desde s[i] que coinciden con los caracteres desde s[0] 2 | 3 | // O(n) 4 | vector z_function(string &s) { 5 | int n = s.size(); 6 | vector z(n); 7 | for (int i = 1, x = 0, y = 0; i < n; i++) { 8 | z[i] = max(0, min(z[i-x], y-i+1)); 9 | while (i+z[i] < n && s[z[i]] == s[i+z[i]]) { 10 | x = i, y = i+z[i], z[i]++; 11 | } 12 | } 13 | return z; 14 | } 15 | -------------------------------------------------------------------------------- /c++/Strings/KMP Automaton.cpp: -------------------------------------------------------------------------------- 1 | const int MAXN = 1e5 + 5, alpha = 26; 2 | const char L = 'A'; 3 | int aut[MAXN][alpha]; // aut[i][j] = a donde vuelvo si estoy en i y pongo una j 4 | 5 | void build(string &s) { 6 | int lps = 0; 7 | aut[0][s[0]-L] = 1; 8 | int n = s.size(); 9 | for (int i = 1; i < n+1; i++) { 10 | for (int j = 0; j < alpha; j++) aut[i][j] = aut[lps][j]; 11 | if (i < n) { 12 | aut[i][s[i]-L] = i + 1; 13 | lps = aut[lps][s[i]-L]; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /java [outdated]/Math/Pollard Rho.java: -------------------------------------------------------------------------------- 1 | La función Rho de Pollard calcula un divisor no trivial de n. 2 | IMPORTANTE: Deben agregarse Modular Multiplication y Greatest common divisor para long. 3 | 4 | public static long rho(long n) { 5 | if ((n&1)==0) return 2; 6 | long i = 0, k = 2, x = 3, y = 3, d; 7 | while (true) { 8 | x = (modmul(x, x, n) + n - 1) % n; 9 | d = gcd(Math.abs(y - x), n); 10 | if (d != 1 && d != n) return d; 11 | if (++i == k) { y = x; k <<= 1; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /java [outdated]/Modular arithmetic/Fibonacci mod m.java: -------------------------------------------------------------------------------- 1 | Calcula fibonacci(n) % m. 2 | 3 | static long fib(long n, long m) { 4 | long a = 0, b = 1, c; 5 | int log2 = (int) (Math.log(n) / Math.log(2)); 6 | for (int i = log2; i >= 0; i--) { 7 | c = a; 8 | a = ((c%m) * (2*(b%m) - (c%m) + m)) % m; 9 | b = ((c%m) * (c%m) + (b%m) * (b%m)) % m; 10 | if (((n >> i) & 1) != 0) { 11 | c = (a + b) % m; 12 | a = b; b = c; 13 | } 14 | } 15 | return a; 16 | } 17 | -------------------------------------------------------------------------------- /c++/Dynamic programming/Min Max Range.cpp: -------------------------------------------------------------------------------- 1 | Devuelve el el minimo de los maximos entre pares de rangos consecutivos haciendo cortes en el Array. 2 | 3 | const int MAX = 1005; 4 | ll dp[MAX][MAX]; 5 | ll sum_ran[MAX][MAX]; 6 | int N; 7 | 8 | ll f(int i, int cuts) { 9 | if (cuts == 0) return sum_ran[i][N-1]; 10 | if (i == N) return 0; 11 | ll &ans = dp[i][cuts]; 12 | if (ans != - 1) return ans; 13 | for (int j = i; j < N; j++) { 14 | ans = min(ans, max(sum_ran[i][j], f(i + 1, cuts - 1))); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /java [outdated]/Geometry/Euclidean Distance.java: -------------------------------------------------------------------------------- 1 | Halla la distancia euclideana de 2 puntos en dos dimensiones (x, y). Para usar el primer método, debe definirse previamente la clase Point 2 | 3 | /*Trabajando con la clase Point*/ 4 | static double euclideanDistance(Point p1, Point p2) { 5 | return Math.hypot(p1.x - p2.x, p1.y - p2.y); 6 | } 7 | /*Trabajando con los valores x y y de cada punto*/ 8 | static double euclideanDistance(double x1, double y1, double x2, double y2) { 9 | return Math.hypot(x2 - x1, y2 - y1); 10 | } 11 | -------------------------------------------------------------------------------- /c++/Graphs/Tree Isomorphism.cpp: -------------------------------------------------------------------------------- 1 | Permite hashear árboles para comparar su estructura rápidamente. 2 | Agregar Random Integer para ll 3 | 4 | map table; 5 | 6 | ll get(ll x) { 7 | if (table.count(x)) return table[x]; 8 | return table[x] = rand(0, 1e18); 9 | } 10 | 11 | ll hashes[N], sum[N]; 12 | 13 | void dfs(int u, int p) { 14 | sum[u] = 0; 15 | for (auto &v : g[u]) { 16 | if (v == p) continue; 17 | dfs(v, u); 18 | sum[u] += hashes[v]; 19 | } 20 | hashes[u] = get(sum[u]); 21 | } 22 | -------------------------------------------------------------------------------- /java [outdated]/Utilities/Lower bound.java: -------------------------------------------------------------------------------- 1 | Dado un arreglo ordenado ascendentemente de tamaño n, busca el elemento x y devuelve la posición de la primera aparición de x, si no lo encuentra devuelve la siguiente posición. Si la posición se sale del arreglo devuelve -1. 2 | 3 | static int lower_bound(int arr[], int x) { 4 | int l = 0, r = arr.length-1; 5 | if (arr[r] < x) return -1; 6 | while (l < r) { 7 | int m = (l+r)/2; 8 | if (arr[m] < x) l = m+1; 9 | else r = m; 10 | } 11 | return l; 12 | } 13 | -------------------------------------------------------------------------------- /java [outdated]/Strings/Suffix Array Longest Common Prefix.java: -------------------------------------------------------------------------------- 1 | Calcula el array Longest Common Prefix para todo el suffix array. IMPORTANTE: Debe haberse ejecutado primero suffixArray(), incluido en Suffix Array Init.java 2 | 3 | static int lcp[] = new int[N_MAX]; 4 | 5 | static void calculateLCP() { 6 | for (int i = 0, l = 0; i < n; i++) { 7 | if (rk[i] > 0) { 8 | int j = sa[rk[i] - 1]; 9 | while (_s[i + l] == _s[j + l]) l++; 10 | lcp[rk[i]] = l; 11 | if (l > 0) l--; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /c++/Utilities/scanf and printf.cpp: -------------------------------------------------------------------------------- 1 | * Lectura segun el tipo de dato (Se usan las mismas para imprimir): 2 | 3 | scanf("%d", &value); // int 4 | scanf("%ld", &value); // long y long int 5 | scanf("%c", &value); // char 6 | scanf("%f", &value); // float 7 | scanf("%lf", &value); // double 8 | scanf("%s", &value); // char* 9 | scanf("%lld", &value); // long long int 10 | scanf("%x", &value); // int hexadecimal 11 | scanf("%o", &value); // int octal 12 | 13 | * Impresion de punto flotante con d decimales, ejemplo 6 decimales: 14 | 15 | printf("%.6lf", value); 16 | -------------------------------------------------------------------------------- /java [outdated]/Geometry/Area.java: -------------------------------------------------------------------------------- 1 | Calcula el area de un polígono representado como un ArrayList de puntos. IMPORTANTE: Definir P[0] = P[n-1] para cerrar el polígono. El algorítmo utiliza el metodo de determinante de la matriz de puntos de la figura. IMPORTANTE: Debe definirse previamente la clase Point. 2 | 3 | public static double area(ArrayList P) { 4 | double result = 0.0; 5 | for (int i = 0; i < P.size()-1; i++) { 6 | result += ((P.get(i).x * P.get(i + 1).y) - (P.get(i + 1).x * P.get(i).y)); 7 | } 8 | return Math.abs(result) / 2.0; 9 | } 10 | -------------------------------------------------------------------------------- /c++/Strings/Minimum Expression.cpp: -------------------------------------------------------------------------------- 1 | Dado un string s devuelve el indice donde comienza la rotación lexicograficamente menor de s. 2 | 3 | // O(n) 4 | int minimum_expression(string s) { 5 | s = s+s; // si no se concatena devuelve el indice del sufijo menor 6 | int len = s.size(), i = 0, j = 1, k = 0; 7 | while (i+k < len && j+k < len) { 8 | if (s[i+k] == s[j+k]) k++; 9 | else if (s[i+k] > s[j+k]) i = i+k+1, k = 0; // cambiar por < para maximum 10 | else j = j+k+1, k = 0; 11 | if (i == j) j++; 12 | } 13 | return min(i, j); 14 | } 15 | -------------------------------------------------------------------------------- /c++/Data structures/Min queue.cpp: -------------------------------------------------------------------------------- 1 | > Funciona como una queue<> que además permite hallar el elemento mínimo en O(1). Para mantener el máximo: cambiar > por <. 2 | 3 | template 4 | struct mnque { 5 | deque dq, mn; 6 | 7 | void push(T x) { 8 | dq.pb(x); 9 | while (mn.size() && mn.back() > x) mn.pop_back(); // o < para max 10 | mn.pb(x); 11 | } 12 | 13 | void pop() { 14 | if (dq.front() == mn.front()) mn.pop_front(); 15 | dq.pop_front(); 16 | } 17 | 18 | T min() { return mn.front(); } 19 | }; 20 | 21 | mnque q; 22 | -------------------------------------------------------------------------------- /c++/Math/Mobius.cpp: -------------------------------------------------------------------------------- 1 | La funcion mu de Mobius devuelve 0 si n es divisible por algun cuadrado (x^2). 2 | Si n es libre de cuadrados entonces devuelve 1 o -1 si n tiene un numero par o impar de factores primos distintos. 3 | * Calcular Mobius para todos los numeros menores o iguales a MX con Sieve of Eratosthenes. 4 | 5 | const int MX = 1e6; 6 | short mu[MX+1] = {0, 1}; 7 | // O(MX log(log(MX))) 8 | void mobius() { 9 | for (int i = 1; i <= MX; i++) { 10 | if (!mu[i]) continue; 11 | for (int j = i*2; j <= MX; j += i) { 12 | mu[j] -= mu[i]; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /java [outdated]/Math/Prime Factorization.java: -------------------------------------------------------------------------------- 1 | Guarda en factors la lista de factores primos de n de menor a mayor. IMPORTANTE: Debe ejecutarse primero Sieve of Eratosthenes (al menos hasta un numero mayor a la raiz cuadrada de n). 2 | 3 | static ArrayList factors = new ArrayList<>(); 4 | 5 | public static void primeFactors(long n) { 6 | factors.clear(); 7 | for (int i = 0, p = primes.get(i); p*p <= n; p = primes.get(++i)) { 8 | while (n % p == 0) { 9 | factors.add(p); 10 | n /= p; 11 | } 12 | } 13 | if (n > 1) factors.add(n); 14 | } 15 | -------------------------------------------------------------------------------- /java [outdated]/Strings/Prefix Function.java: -------------------------------------------------------------------------------- 1 | Dado un string s retorna un array pf donde pf[i] es el largo del prefijo propio más largo 2 | que tambien es sufijo de cad[0] hasta cad[i]. 3 | El String debe pasarse como un array de chars cadena.toCharArray(); 4 | // O(n) 5 | 6 | static int[] prefix_function(char[] cad) { 7 | int n = cad.length; 8 | int pf[] = new int[n]; 9 | pf[0] = 0; 10 | for (int i = 1, j = 0; i < n; i++) { 11 | while (j==1 && cad[i] != cad[j]) j = pf[j-1]; 12 | if (cad[i] == cad[j]) j++; 13 | pf[i] = j; 14 | } 15 | return pf; 16 | } 17 | -------------------------------------------------------------------------------- /java [outdated]/Utilities/Bit Manipulation.java: -------------------------------------------------------------------------------- 1 | Operaciones a nivel de bits. 2 | 3 | n & 1 -> Verifica si n es impar o no 4 | n & (1< Verifica si el k-esimo bit esta encendido o no 5 | n | (1< Enciende el k-esimo bit 6 | n & ~(1< Apaga el k-esimo bit 7 | n ^ (1< Invierte el k-esimo bit 8 | ~n -> Invierte todos los bits 9 | n & -n -> Devuelve el bit encendido mas a la derecha 10 | ~n & (n+1) -> Devuelve el bit apagado mas a la derecha 11 | n | (n+1) -> Enciende el bit apagado mas a la derecha 12 | n & (n-1) -> Apaga el bit encendido mas a la derecha 13 | -------------------------------------------------------------------------------- /c++/Data structures/Ordered Set.cpp: -------------------------------------------------------------------------------- 1 | > Funciona como un set<> que además cuenta con dos funciones adicionales. 2 | 3 | #include 4 | #include 5 | using namespace __gnu_pbds; 6 | template 7 | using ordered_set = tree, rb_tree_tag, 8 | tree_order_statistics_node_update>; 9 | 10 | ordered_set st; 11 | st.find_by_order(k) // Retorna iterador al k-ésimo elemento más pequeño 12 | // Si k >= st.size() entonces retorna st.end() 13 | st.order_of_key(x) // Retorna cuántos elementos hay menores que x 14 | -------------------------------------------------------------------------------- /java [outdated]/Strings/Z-Function.java: -------------------------------------------------------------------------------- 1 | Dado un string s retorna un arreglo z donde z[i] es igual al mayor numero de caracteres desde s[i] que coinciden con los caracteres desde s[0] 2 | 3 | static int[] z_function(String ss) { 4 | StringBuilder s = new StringBuilder(ss); 5 | int n = s.length(); 6 | int[] z = new int[n]; 7 | for (int i = 1, x = 0, y = 0; i < n; i++) { 8 | z[i] = Math.max(0, Math.min(z[i - x], y - i + 1)); 9 | while (i + z[i] < n && s.charAt(z[i]) == s.charAt(i + z[i])) { 10 | x = i; y = i + z[i]; z[i]++; 11 | } 12 | } 13 | return z; 14 | } 15 | -------------------------------------------------------------------------------- /java [outdated]/Math/Sieve of Eratosthenes.java: -------------------------------------------------------------------------------- 1 | Guarda en primes los números primos menores o iguales a MAX. Para saber si p es un número primo, hacer: if (!marked[p]) 2 | 3 | static int MAX = 1000000; 4 | static int SQRT = 1000; 5 | static ArrayList primes = new ArrayList<>(); 6 | static boolean marked[] = new boolean[MAX+1]; 7 | 8 | static void sieve() { 9 | marked[1] = true; 10 | int i = 2; 11 | for (; i <= SQRT; ++i) if (!marked[i]) { 12 | primes.add(i); 13 | for (int j = i*i; j <= MAX; j += i) marked[j] = true; 14 | } 15 | for (; i <= MAX; ++i) if (!marked[i]) primes.add(i); 16 | } 17 | -------------------------------------------------------------------------------- /java [outdated]/Dynamic Programming/Min Max Range.java: -------------------------------------------------------------------------------- 1 | // Devuelve el el minimo de los maximos entre pares de rangos consecutivos haciendo cortes en el Array. 2 | 3 | static final int MAX = 1005; 4 | static long dp[][] = new long[MAX][MAX]; 5 | static long sum_ran[][] = new long [MAX][MAX]; 6 | static int N; 7 | 8 | static long f(int i, int cuts) { 9 | if (cuts == 0) return sum_ran[i][N-1]; 10 | if (i == N) return 0; 11 | long ans = dp[i][cuts]; 12 | if (ans != - 1) return ans; 13 | for (int j = i; j < N; j++) { 14 | ans = Math.min(ans, Math.max(sum_ran[i][j], f(i + 1, cuts - 1))); 15 | } 16 | return ans; 17 | } 18 | -------------------------------------------------------------------------------- /java [outdated]/Math/Mobius.java: -------------------------------------------------------------------------------- 1 | La función mu de Mobius devuelve 0 si n es divisible por algún cuadrado. 2 | Si n es libre de cuadrados entonces devuelve 1 o -1 si n tiene un número par o impar de factores primos distintos. 3 | * Calcular Mobius para todos los numeros menores o iguales a MAX con Sieve of Eratosthenes. 4 | 5 | static final int MAX = 1000000; 6 | static short mu[] = new short [MAX+1]; 7 | 8 | // O(MAX log(log(MAX))) 9 | static void mobius() { 10 | mu[0] = 0; mu[1] = 1; 11 | for (int i = 1; i <= MAX; i++) if (mu[i]==1) { 12 | for (int j = i+i; j <= MAX; j += i) { 13 | mu[j] -= mu[i]; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /c++/Values sequences and results/Time Complexities.tex: -------------------------------------------------------------------------------- 1 | Aproximación del mayor número n de datos que pueden procesarse para cada una de las complejidades algoritmicas. Tomar esta tabla solo como referencia. 2 | 3 | \begin{tabbing} 4 | \textbf{Complexity}\hspace{4cm} \= \textbf{n}\hspace{3cm} \\ 5 | $O(n!)$ \> 11\\ 6 | $O(n^{5})$ \> 50\\ 7 | $O(2^{n}*n^{2})$ \> 18\\ 8 | $O(2^{n}*n)$ \> 22\\ 9 | $O(n^{4})$ \> 100\\ 10 | $O(n^{3})$ \> 500\\ 11 | $O(n^{2}\log_{2}n)$ \> 1.000\\ 12 | $O(n^{2})$ \> 10.000\\ 13 | $O(n\log_{2}n)$ \> $10^{6}$\\ 14 | $O(n)$ \> $10^{8}$\\ 15 | $O(\sqrt{n})$ \> $10^{16}$\\ 16 | $O(\log_{2}n)$ \> -\\ 17 | $O(1)$ \> -\\ 18 | \end{tabbing} 19 | -------------------------------------------------------------------------------- /java [outdated]/Values sequences and results/Time Complexities.tex: -------------------------------------------------------------------------------- 1 | 2 | Aproximación del mayor número n de datos que pueden procesarse para cada una de las complejidades algoritmicas. Tomar esta tabla solo como referencia. 3 | 4 | \begin{tabbing} 5 | \textbf{Complexity}\hspace{4cm} \= \textbf{n}\hspace{3cm} \\ 6 | $O(n!)$ \> 11\\ 7 | $O(n^{5})$ \> 50\\ 8 | $O(2^{n}*n^{2})$ \> 18\\ 9 | $O(2^{n}*n)$ \> 22\\ 10 | $O(n^{4})$ \> 100\\ 11 | $O(n^{3})$ \> 500\\ 12 | $O(n^{2}\log_{2}n)$ \> 1.000\\ 13 | $O(n^{2})$ \> 10.000\\ 14 | $O(n\log_{2}n)$ \> $10^{6}$\\ 15 | $O(n)$ \> $10^{8}$\\ 16 | $O(\sqrt{n})$ \> $10^{16}$\\ 17 | $O(\log_{2}n)$ \> -\\ 18 | $O(1)$ \> -\\ 19 | \end{tabbing} 20 | -------------------------------------------------------------------------------- /java [outdated]/Strings/KMP's Algorithm.java: -------------------------------------------------------------------------------- 1 | Encuentra si el string pattern se encuentra en el string cadena. Debe estar definido el método prefix_function. 2 | 3 | import java.util.ArrayList; 4 | 5 | static boolean kmp(String cadena, String pattern) { 6 | int n=cadena.length(); 7 | int m=pattern.length(); 8 | ArrayList tab=prefix_function(pattern); 9 | 10 | for (int i = 0, seen = 0; i < n; i++) { 11 | while (seen > 0 && cadena.charAt(i) != pattern.charAt(seen)) { 12 | seen = tab.get(seen-1); 13 | } 14 | if (cadena.charAt(i) == pattern.charAt(seen)) seen++; 15 | if (seen == m) return true; 16 | } 17 | return false; 18 | } 19 | -------------------------------------------------------------------------------- /java [outdated]/Strings/Suffix Array String Matching Boolean.java: -------------------------------------------------------------------------------- 1 | Busca el string p en el string s (definido en init), y retorna true si se encuentra, o false en caso contrario. Debe inicializarse m con el tamaño de p, y debe ejecutarse previamente suffixArray() de Suffix Array Init.java. 2 | 3 | static String p; 4 | static int m; 5 | 6 | static boolean stringMatching() { 7 | if (m - 1 > n) return false; 8 | char [] _p = p.toCharArray(); 9 | int l = 0, h = n - 1, c = l; 10 | while (l <= h) { 11 | c = (l + h) / 2; 12 | int r = strncmp(_s, sa[c], _p); 13 | if (r > 0) h = c - 1; 14 | else if (r < 0) l = c + 1; 15 | else return true; 16 | } 17 | return false; 18 | } 19 | -------------------------------------------------------------------------------- /c++/Graphs/Floyd Warshall.cpp: -------------------------------------------------------------------------------- 1 | Dado un grafo halla la distancia minima entre cualquier par de nodos. g[i][j] guardara la distancia minima entre el nodo i y el j. 2 | 3 | const int inf = 1e9; 4 | const int MX = 505; // Cantidad maxima de nodos 5 | int g[MX][MX]; // Matriz de adyacencia 6 | int n, m; // Cantidad de nodos y aristas 7 | 8 | void floydWarshall() { 9 | for (int k = 0; k < n; k++) 10 | for (int i = 0; i < n; i++) 11 | for (int j = 0; j < n; j++) 12 | g[i][j] = min(g[i][j], g[i][k] + g[k][j]); 13 | } 14 | 15 | void init() { 16 | for (int i = 0; i <= n; i++) { 17 | for (int j = 0; j <= n; j++) { 18 | g[i][j] = (i == j ? 0 : inf); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /c++/Math/Basis of a Vector Space (mod 2 Field).cpp: -------------------------------------------------------------------------------- 1 | Dado un arreglo A con n numeros calcula en basis[] las mascaras con las cuales se pueden generar todos los diferentes xor que se generan al hacer xor entre los elementos de cualquier subconjunto A. La cantidad de xor diferentes es 2^sz. 2 | 3 | const int D = 30; // maxima cantidad de bits 4 | int basis[D]; 5 | int sz; // cantidad de mascaras en la base 6 | 7 | // O(n*D) 8 | void insertVector(int mask) { 9 | for (int i = 0; i < D; ++i) { 10 | if (mask & (1< prefix_function(String s) { 5 | int n = s.length(), len = 0, i = 1; 6 | ArrayList lps = new ArrayList<>(); 7 | Collections.fill(lps, n); 8 | lps.set(len, 0); 9 | while (i < n) { 10 | if (s.charAt(len) != s.charAt(i)) { 11 | if (len > 0) len = lps.get(len-1); 12 | else lps.set(i++, len); 13 | } else lps.set(i++, ++len); 14 | } 15 | // lps.add(0, -1); // Para SuffixLink 16 | return lps; 17 | } 18 | -------------------------------------------------------------------------------- /c++/Data structures/Sparse Table.cpp: -------------------------------------------------------------------------------- 1 | > Permite realizar consultas sobre rangos, no actualizaciones. 2 | > Soporta operaciones en las que no importa si se solapan los rangos, por ejemplo: max y min se pueden pero suma no. 3 | > Construcción y memoria O(nlon), consultas en O(1). 4 | 5 | const int N = 1e5+5; 6 | const int LG = log2(N)+1; 7 | int spt[LG][N]; 8 | int arr[N]; 9 | int n; 10 | 11 | void build() { 12 | for (int i = 0; i < n; i++) spt[0][i] = arr[i]; 13 | for (int j = 0; j < LG-1; j++) 14 | for (int i = 0; i+(1<<(j+1)) <= n; i++) 15 | spt[j+1][i] = min(spt[j][i], spt[j][i+(1< g[MX]; // Lista de adyacencia 6 | vector vis; // Marca los nodos ya visitados 7 | int n, m; // Cantidad de nodos y aristas 8 | 9 | void dfs(int u) { 10 | vis[u] = true; 11 | for (auto &v : g[u]) { 12 | if (!vis[v]) dfs(v); 13 | } 14 | } 15 | 16 | void init() { 17 | vis.assign(n, false); 18 | for (int i = 0; i <= n; i++) { 19 | g[i].clear(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /java [outdated]/Strings/Suffix Array Longest Common Substring.java: -------------------------------------------------------------------------------- 1 | Busca el substring común mas largo entre dos strings. Retorna un int[2], con el size del substring y uno de los indices del suffix array. Debe ejecutarse previamente suffixArray() y calculateLCP() 2 | 3 | // Los substrings deben estar concatenados de la forma "string1#string2$", antes de ejecutar suffixArray() y calculateLCS() 4 | // m debe almacenar el size del string2. 5 | 6 | static int[] longestCommonSubstring() { 7 | int i, ans[] = new int[2]; 8 | ans[0] = -1; ans[1] = 0; 9 | for (i = 1; i < n; i++) { 10 | if (((sa[i] < n - m - 1) != (sa[i - 1] < n - m - 1)) && lcp[i] > ans[0]) { 11 | ans[0] = lcp[i]; ans[1] = i; 12 | } 13 | } 14 | return ans; 15 | } 16 | -------------------------------------------------------------------------------- /c++/Graphs/Cycle Detection.cpp: -------------------------------------------------------------------------------- 1 | Determina si un grafo dirigido tiene o no ciclos (si es un DAG o no). 2 | 3 | const int MX = 1e5+5; // Cantidad maxima de nodos 4 | vector g[MX]; // Lista de adyacencia 5 | vector vis; // Marca el estado de los nodos ya visitados 6 | bool cycle; // true si el grafo tiene ciclos 7 | int n, m; // Cantidad de nodos y aristas 8 | 9 | void dfs(int u) { 10 | if (cycle) return; 11 | vis[u] = 1; 12 | for (auto &v : g[u]) { 13 | if (!vis[v]) dfs(v); 14 | else if (vis[v] == 1) { 15 | cycle = true; 16 | break; 17 | } 18 | } 19 | vis[u] = 2; 20 | } 21 | 22 | void init() { 23 | vis.assign(n, 0); 24 | for (int i = 0; i <= n; i++) { 25 | g[i].clear(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /c++/Math/Miller Rabin.cpp: -------------------------------------------------------------------------------- 1 | El algoritmo de Miller-Rabin determina si un numero es primo o no. Agregar Modular Exponentiation (para m ll) y Modular Multiplication. 2 | 3 | // O(log^3(n)) 4 | bool test(ll n, int a) { 5 | if (n == a) return true; 6 | ll s = 0, d = n-1; 7 | while (d%2 == 0) s++, d /= 2; 8 | ll x = expmod(a, d, n); 9 | if (x == 1 || x+1 == n) return true; 10 | for (int i = 0; i < s-1; i++) { 11 | x = mulmod(x, x, n); 12 | if (x == 1) return false; 13 | if (x+1 == n) return true; 14 | } 15 | return false; 16 | } 17 | 18 | bool is_prime(ll n) { 19 | if (n == 1) return false; 20 | int ar[] = {2, 3, 5, 7, 11, 13, 17, 19, 23}; 21 | for (auto &p : ar) if (!test(n, p)) return false; 22 | return true; 23 | } 24 | -------------------------------------------------------------------------------- /c++/Modular arithmetic/Chinese Remainder Theorem.cpp: -------------------------------------------------------------------------------- 1 | Encuentra un x tal que para cada i : x es congruente con A_i mod M_i 2 | Devuelve {x, lcm}, donde x es la solucion con modulo lcm (lcm = LCM(M_0, M_1, ...)). Dado un k : x + k*lcm es solucion tambien. 3 | Si la solucion no existe o la entrada no es valida devuelve {-1, -1} 4 | Agregar Extended Euclides. 5 | 6 | pii crt(vector A, vector M) { 7 | int n = A.size(), ans = A[0], lcm = M[0]; 8 | for (int i = 1; i < n; i++) { 9 | int d = euclid(lcm, M[i]); 10 | if ((A[i] - ans) % d) return {-1, -1}; 11 | int mod = lcm / d * M[i]; 12 | ans = (ans + x * (A[i] - ans) / d % (M[i] / d) * lcm) % mod; 13 | if (ans < 0) ans += mod; 14 | lcm = mod; 15 | } 16 | return {ans, lcm}; 17 | } 18 | -------------------------------------------------------------------------------- /java [outdated]/Graphs/Floyd Warshall.java: -------------------------------------------------------------------------------- 1 | Dado un grafo halla la distancia mínima entre cualquier par de nodos. g[i][j] guardará la distancia mínima entre el nodo i y el j. 2 | 3 | static final int INF = (1<<30); 4 | static final int MAX = 505; // Cantidad maxima de nodos 5 | static int g[][]= new int[MAX][MAX]; // Matriz de adyacencia 6 | static int N, M; // Cantidad de nodos y aristas 7 | 8 | static void floydWarshall() { 9 | for (int k = 0; k < N; k++) 10 | for (int i = 0; i < N; i++) 11 | for (int j = 0; j < N; j++) 12 | g[i][j] = Math.min(g[i][j], g[i][k] + g[k][j]); 13 | } 14 | 15 | static void init() { 16 | for (int i = 0; i <= N; i++) { 17 | for (int j = 0; j <= N; j++) { 18 | g[i][j] = INF; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /java [outdated]/Utilities/Template.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.lang.*; 3 | import java.io.*; 4 | import java.math.*; 5 | 6 | class Main { 7 | 8 | static Scanner in = new Scanner(new BufferedReader(new InputStreamReader(System.in))); 9 | static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out))); 10 | 11 | public static void main(String[] args) { 12 | // Tu código... 13 | int a = Integer.parseInt(in.next()); 14 | int b = Integer.parseInt(in.next()); 15 | double c = a + b; 16 | // Para imprimir con 6 decimales 17 | // Locale.setDefault(Locale.US); 18 | // out.printf("%.6f\n", c); 19 | out.println(c); 20 | out.close(); // Obligatorio al finalizar el programa 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /c++/Data structures/Fenwick Tree.cpp: -------------------------------------------------------------------------------- 1 | > !! Usar indexando desde 1 en vez de 0. Permite procesar consultas de suma en rangos y actualizaciones puntuales sobre un arreglo. 2 | 3 | const int N = 1e5; 4 | int bit[N+1]; 5 | 6 | void add(int k, int val) { 7 | for (; k <= N; k += k&-k) bit[k] += val; 8 | } 9 | 10 | int rsq(int k) { 11 | int sum = 0; 12 | for (; k >= 1; k -= k&-k) sum += bit[k]; 13 | return sum; 14 | } 15 | 16 | int rsq(int i, int j) { return rsq(j) - rsq(i-1); } 17 | // Ultimo valor <= o < a val 18 | int lower_find(int val) { 19 | int id = 0; 20 | for (int i = 31-__builtin_clz(N); i >= 0; --i) { 21 | int nid = id | (1< manacher(string &s) { 11 | string t = parse(s); 12 | int n = t.size(), c = 0, r = 0; 13 | vector p(n, 0); 14 | for (int i = 1; i < n-1; i++) { 15 | int j = c - (i-c) ; 16 | if (r > i) p[i] = min(r-i, p[j]); 17 | while (t[i+1+p[i]] == t[i-1-p[i]]) 18 | p[i]++; 19 | if (i+p[i] > r) { 20 | c = i; 21 | r = i+p[i]; 22 | } 23 | } 24 | return p; 25 | // si p[i] > 0 entonces, s[l, r) es palíndromo 26 | // donde l = (i-1-p[i])/2 y r = l+p[i]; 27 | } 28 | -------------------------------------------------------------------------------- /java [outdated]/Data Structures/Sparse Table.java: -------------------------------------------------------------------------------- 1 | Estructura de datos que permite procesar consultas por rangos. 2 | 3 | static int MAX_N = 1000; 4 | static int K = (int)(Math.log(MAX_N)/Math.log(2))+1; 5 | static int st[][] = new int[MAX_N][K]; 6 | static int _log2[] = new int[MAX_N+1]; 7 | static int A[] = new int[MAX_N]; 8 | int n; 9 | 10 | void calc_log2() { 11 | _log2[1] = 0; 12 | for (int i = 2; i <= MAX_N; i++) _log2[i] = _log2[i/2] + 1; 13 | } 14 | 15 | void build() { 16 | for (int i = 0; i < n; i++) st[i][0] = A[i]; 17 | for (int j = 1; j <= K; j++) 18 | for (int i = 0; i + (1 << j) <= n; i++) 19 | st[i][j] = Math.min(st[i][j-1], st[i + (1 << (j - 1))][j - 1]); 20 | } 21 | 22 | int rmq(int i, int j) { 23 | int k = _log2[j-i+1]; 24 | return Math.min(st[i][k], st[j - (1 << k) + 1][k]); 25 | } 26 | -------------------------------------------------------------------------------- /java [outdated]/Dynamic Programming/Longest Common Subsequence.java: -------------------------------------------------------------------------------- 1 | Dados dos Strings, encuentra el largo de la subsecuencia en común mas larga entre ellas. 2 | 3 | static int M_MAX = 20; // Máximo size del String 1 4 | static int N_MAX = 20; // Máximo size del String 2 5 | static int m, n; // Size de Strings 1 y 2 6 | static char X[]; // toCharArray del String 1 7 | static char Y[]; // toCharArray del String 2 8 | static int memo[][] = new int[M_MAX + 1][N_MAX + 1]; 9 | 10 | static int lcs(int m, int n) { 11 | for (int i = 0; i <= m; i++) { 12 | for (int j = 0; j <= n; j++) { 13 | if (i == 0 || j == 0) memo[i][j] = 0; 14 | else if (X[i - 1] == Y[j - 1]) memo[i][j] = memo[i - 1][j - 1] + 1; 15 | else memo[i][j] = Math.max(memo[i - 1][j], memo[i][j - 1]); 16 | } 17 | } 18 | return memo[m][n]; 19 | } 20 | -------------------------------------------------------------------------------- /java [outdated]/Graphs/DFS.java: -------------------------------------------------------------------------------- 1 | Búsqueda en profundidad sobre grafos. Recibe un nodo inicial u y visita todos los nodos alcanzables desde u. 2 | DFS puede ser usado para contar la cantidad de componentes conexas en un grafo y puede ser modificado para que retorne información de los nodos dependiendo del problema. 3 | 4 | static final int MAX = 100005; // Cantidad maxima de nodos 5 | static ArrayList g[] = new ArrayList[MAX]; // Lista de adyacencia 6 | static boolean[] vis = new boolean[MAX]; // Marca los nodos ya visitados 7 | static int N, M; // Cantidad de nodos y aristas 8 | 9 | static void dfs(int u) { 10 | vis[u] = true; 11 | for (int v : g[u]) { 12 | if (!vis[v]) dfs(v); 13 | } 14 | } 15 | 16 | static void init() { 17 | for (int i = 0; i <= N; i++) { 18 | g[i] = new ArrayList<>(); 19 | vis[i] = false; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /java [outdated]/Math/Miller-Rabin.java: -------------------------------------------------------------------------------- 1 | La función de Miller-Rabin determina si un número dado es o no un número primo. IMPORTANTE: Debe agregarse los métodos de Modular Exponentiation y Modular Multiplication. 2 | 3 | public static boolean isPrime(long p) { 4 | if (p < 2 || (p != 2 && p % 2 == 0)) { 5 | return false; 6 | } 7 | long s = p - 1; 8 | while (s % 2 == 0) { 9 | s /= 2; 10 | } 11 | for (int i = 0; i < 5; i++) { 12 | long a = (long) (Math.random() * p) % (p - 1) + 1; 13 | long temp = s; 14 | long mod = modpow(a, temp, p); 15 | while (temp != p - 1 && mod != 1 && mod != p - 1) { 16 | mod = modmul(mod, mod, p); 17 | temp *= 2; 18 | } 19 | if (mod != p - 1 && temp % 2 == 0) { 20 | return false; 21 | } 22 | } 23 | return true; 24 | } 25 | -------------------------------------------------------------------------------- /c++/Modular arithmetic/Linear Recurrence.cpp: -------------------------------------------------------------------------------- 1 | Calcula el n-esimo termino de una recurrencia lineal (que depende de los k terminos anteriores). 2 | * Llamar init(k) en el main una unica vez si no es necesario inicializar las matrices multiples veces. 3 | Este ejemplo calcula el fibonacci de n como la suma de los k terminos anteriores de la secuencia (En la secuencia comun k es 2). 4 | Agregar Matrix Multiplication con un construcctor vacio. 5 | 6 | matrix F, T; 7 | 8 | void init(int k) { 9 | F = {k, 1}; // primeros k terminos 10 | F[k-1][0] = 1; 11 | T = {k, k}; // fila k-1 = coeficientes: [c_k, c_k-1, ..., c_1] 12 | for (int i = 0; i < k-1; i++) T[i][i+1] = 1; 13 | for (int i = 0; i < k; i++) T[k-1][i] = 1; 14 | } 15 | // O(k^3 log(n)) 16 | int fib(ll n, int k = 2) { 17 | init(k); 18 | matrix ans = pow(T, n+k-1) * F; 19 | return ans[0][0]; 20 | } 21 | -------------------------------------------------------------------------------- /java [outdated]/Geometry/Point in Polygon.java: -------------------------------------------------------------------------------- 1 | Determina si un punto pt se encuentra en el polígono P. Este polígono se define como un vector de puntos, donde el punto 0 y n-1 son el mismo. IMPORTANTE: Deben incluirse las estructuras point y vec, ademas del método angle y el método cross que se encuentra en Collinear Points. 2 | 3 | static boolean ccw(Point p, Point q, Point r) { 4 | return cross(toVector(p, q), toVector(p, r)) > 0; 5 | } 6 | 7 | static boolean inPolygon(Point pt, ArrayList P) { 8 | if (P.size() == 0) return false; 9 | double sum = 0; 10 | for (int i = 0; i < P.size()-1; i++) { 11 | if (ccw(pt, P.get(i), P.get(i+1))) sum += angle(P.get(i), pt, P.get(i+1)); 12 | else sum -= angle(P.get(i), pt, P.get(i+1)); 13 | } 14 | if (Math.abs(Math.abs(sum) - 2*Math.acos(-1.0)) < 1e-9) return true; 15 | return false; 16 | } 17 | -------------------------------------------------------------------------------- /java [outdated]/Data Structures/Fenwick Tree.java: -------------------------------------------------------------------------------- 1 | Estructura de datos que permite procesar consultas por rangos y actualizaciones individuales sobre un arreglo. 2 | 3 | static int N = 100000; 4 | static int bit[] = new int[N+1]; 5 | 6 | void add(int k, int val) { 7 | for (; k <= N; k += k&-k) bit[k] += val; 8 | } 9 | 10 | int rsq(int k) { 11 | int sum = 0; 12 | for (; k >= 1; k -= k&-k) sum += bit[k]; 13 | return sum; 14 | } 15 | 16 | int rsq(int i, int j) { return rsq(j) - rsq(i-1); } 17 | 18 | int lower_find(int val) { // last value < or <= to val 19 | int idx = 0; 20 | for (int i = 31-Integer.numberOfLeadingZeros(N); i >= 0; --i) { 21 | int nidx = idx | (1 << i); 22 | if (nidx <= N && bit[nidx] <= val) { // change <= to < 23 | val -= bit[nidx]; 24 | idx = nidx; 25 | } 26 | } 27 | return idx; 28 | } 29 | -------------------------------------------------------------------------------- /c++/Graphs/Flood Fill.cpp: -------------------------------------------------------------------------------- 1 | Dado un grafo implicito como matriz, "colorea" y cuenta el tamaño de las componentes conexas. 2 | Esta funcion debe ser llamada con las coordenadas (i, j) donde se inicia el recorrido, busca cada caracter c1 de la componente, los remplaza por el caracter c2 y retorna el tamaño. 3 | 4 | const int MX = 1e3; // Tamanio maximo de la matriz 5 | int dy[] = {1, 1, 0,-1,-1,-1, 0, 1}; // Posibles movimientos: 6 | int dx[] = {0, 1, 1, 1, 0,-1,-1,-1}; // (8 direcciones) 7 | char grid[MX][MX]; // Matriz de caracteres 8 | int n, m; // Tamanio de la matriz 9 | 10 | int floodfill(int y, int x, char c1, char c2) { 11 | if (y < 0 || y >= n || x < 0 || x >= m) return 0; 12 | if (grid[y][x] != c1) return 0; 13 | grid[y][x] = c2; 14 | int ans = 1; 15 | for (int i = 0; i < 8; i++) { 16 | ans += floodfill(y + dy[i], x + dx[i], c1, c2); 17 | } 18 | return ans; 19 | } 20 | -------------------------------------------------------------------------------- /c++/Graphs/Topological Sort.cpp: -------------------------------------------------------------------------------- 1 | Dado un grafo aciclico dirigido (DAG), ordena los nodos linealmente de tal manera que si existe una arista entre los nodos u y v entonces u aparece antes que v. 2 | Este ordenamiento es una manera de poner todos los nodos en una linea recta de tal manera que las aristas vayan de izquierda a derecha. 3 | 4 | const int MX = 1e5+5; // Cantidad maxima de nodos 5 | vector g[MX]; // Lista de adyacencia 6 | vector vis; // Marca los nodos ya visitados 7 | deque order; // Orden topologico del grafo 8 | int n, m; // Cantidad de nodos y aristas 9 | 10 | void toposort(int u) { 11 | vis[u] = true; 12 | for (auto &v : g[u]) { 13 | if (!vis[v]) toposort(v); 14 | } 15 | order.push_front(u); 16 | } 17 | 18 | void init() { 19 | order.clear(); 20 | vis.assign(n, false); 21 | for (int i = 0; i <= n; i++) { 22 | g[i].clear(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /c++/Modular arithmetic/Discrete Logarithm.cpp: -------------------------------------------------------------------------------- 1 | Devuelve un entero x tal que a^x = b (mod m) or -1 si no existe tal x. Agregar Modular Exponentiation. 2 | 3 | ll discrete_log(ll a, ll b, ll m) { 4 | a %= m, b %= m; 5 | if (b == 1) return 0; 6 | int cnt = 0; 7 | ll tmp = 1; 8 | for (int g = __gcd(a, m); g != 1; g = __gcd(a, m)) { 9 | if (b%g) return -1; 10 | m /= g, b /= g; 11 | tmp = tmp*a / g % m; 12 | ++cnt; 13 | if (b == tmp) return cnt; 14 | } 15 | map w; 16 | int s = ceil(sqrt(m)); 17 | ll base = b; 18 | for (int i = 0; i < s; i++) { 19 | w[base] = i; 20 | base = base*a % m; 21 | } 22 | base = expmod(a, s, m); 23 | ll key = tmp; 24 | for (int i = 1; i <= s+1; i++) { 25 | key = key*base % m; 26 | if (w.count(key)) return i*s - w[key] + cnt; 27 | } 28 | return -1; 29 | } 30 | -------------------------------------------------------------------------------- /c++/Graphs/Kruskal.cpp: -------------------------------------------------------------------------------- 1 | Dado un grafo con pesos halla su arbol cobertor minimo. Debe agregarse Disjoint Set. 2 | 3 | struct edge { int u, v, w; }; 4 | 5 | bool cmp(edge &a, edge &b) { 6 | return a.w < b.w; 7 | } 8 | 9 | const int MX = 1e5+5; // Cantidad maxima de nodos 10 | vector g[MX]; // Lista de adyacencia 11 | vector e; // Lista de aristas 12 | int n, m; // Cantidad de nodos y aristas 13 | 14 | void kruskall() { 15 | sort(e.begin(), e.end(), cmp); 16 | dsu ds(n); 17 | int cnt = 0; 18 | for (auto &ed : e) { 19 | if (ds.find(ed.u) != ds.find(ed.v)) { 20 | ds.unite(ed.u, ed.v); 21 | g[ed.u].pb({ed.v, ed.w}); 22 | g[ed.v].pb({ed.u, ed.w}); 23 | if (++cnt == n-1) break; 24 | } 25 | } 26 | } 27 | 28 | void init() { 29 | e.clear(); 30 | for (int i = 0; i <= n; i++) { 31 | g[i].clear(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /c++/Modular arithmetic/Pisano Period.cpp: -------------------------------------------------------------------------------- 1 | Calcula el Periodo de Pisano de m, que es el periodo con el cual se repite la Sucesion de Fibonacci modulo m. 2 | Si m es primo el algoritmo funciona (considerable) para m < 10^6. Aregar Modular Exponentiation (sin el modulo) y Lowest Common Multiple (para ll). 3 | 4 | ll period(ll m) { 5 | ll a = 0, b = 1, c, pp = 0; 6 | do { 7 | c = (a+b) % m; 8 | a = b; b = c; pp++; 9 | } while (a != 0 || b != 1); 10 | return pp; 11 | } 12 | 13 | ll pisanoPrime(ll p, int e) { 14 | return expmod(p, e-1) * period(p); 15 | } 16 | 17 | ll pisanoPeriod(ll m) { 18 | ll pp = 1; 19 | for (ll p = 2; p <= m/p; p++) { 20 | if (m%p == 0) { 21 | int e = 0; 22 | while (m%p == 0) e++, m /= p; 23 | pp = lcm(pp, pisanoPrime(p, e)); 24 | } 25 | } 26 | if (m > 1) pp = lcm(pp, period(m)); 27 | return pp; 28 | } 29 | -------------------------------------------------------------------------------- /c++/Data structures/Disjoint Set.cpp: -------------------------------------------------------------------------------- 1 | > Permite mantener una colección de conjuntos disyuntos. find(u) indica a qué conjunto pertenece u. unite(u, v) une los conjuntos de u y v en uno. 2 | 3 | struct dsu { 4 | vector par, sz; 5 | int size; // Cantidad de conjuntos 6 | 7 | dsu(int n) : par(n), sz(n, 1) { 8 | size = n; 9 | iota(par.begin(), par.end(), 0); 10 | } 11 | // Busca el nodo representativo del conjunto de u 12 | int find(int u) { 13 | return par[u] == u ? u : (par[u] = find(par[u])); 14 | } 15 | // Une los conjuntos de u y v 16 | void unite(int u, int v) { 17 | u = find(u), v = find(v); 18 | if (u == v) return; 19 | if (sz[u] > sz[v]) swap(u, v); 20 | par[u] = v; 21 | sz[v] += sz[u]; 22 | size--; 23 | } 24 | // Cantidad de elementos en el conjunto de u 25 | int count(int u) { return sz[find(u)]; } 26 | }; 27 | -------------------------------------------------------------------------------- /c++/Graphs/BFS.cpp: -------------------------------------------------------------------------------- 1 | Busqueda en anchura sobre grafos. Recibe un nodo inicial u y visita todos los nodos alcanzables desde u. 2 | BFS tambien halla la distancia mas corta entre el nodo inicial u y los demas nodos si todas las aristas tienen peso 1. 3 | 4 | const int MX = 1e5+5; // Cantidad maxima de nodos 5 | vector g[MX]; // Lista de adyacencia 6 | vector dist; // Almacena la distancia a cada nodo 7 | int n, m; // Cantidad de nodos y aristas 8 | 9 | void bfs(int u) { 10 | queue q; 11 | q.push(u); 12 | dist[u] = 0; 13 | 14 | while (q.size()) { 15 | u = q.front(); 16 | q.pop(); 17 | for (auto &v : g[u]) { 18 | if (dist[v] == -1) { 19 | dist[v] = dist[u] + 1; 20 | q.push(v); 21 | } 22 | } 23 | } 24 | } 25 | 26 | void init() { 27 | dist.assign(n, -1); 28 | for (int i = 0; i <= n; i++) { 29 | g[i].clear(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /java [outdated]/Modular arithmetic/Chinese Remainder Theorem.java: -------------------------------------------------------------------------------- 1 | Encuentra un x tal que para cada i : x es congruente con A_i mod M_i 2 | Devuelve un vector con dos posiciones donde [0] = x && [1] = lcm 3 | donde x es la solución con modulo lcm (lcm = LCM(M_0, M_1, ...)). Dado un k : x + k*lcm es solución tambien. 4 | Si la solución no existe o la entrada no es válida devuelve {-1, -1} 5 | --> Agregar Extended Euclides <-- 6 | 7 | static int[] crt(ArrayList A, ArrayList M) { 8 | int n = A.size(), ans = A.get(0), lcm = M.get(0); 9 | for (int i = 1; i < n; i++) { 10 | int d = euclid(lcm, M.get(i)); 11 | if (((A.get(i) - ans) % d) == 1) { int y[] = {-1, -1}; return y; }; 12 | int mod = lcm / d * M.get(i); 13 | ans = (ans + x * (A.get(i) - ans) / d % (M.get(i) / d) * lcm) % mod; 14 | if (ans < 0) ans += mod; 15 | lcm = mod; 16 | } 17 | int y[] = {ans, lcm}; 18 | return y; 19 | } 20 | -------------------------------------------------------------------------------- /c++/Math/Euler Totient.cpp: -------------------------------------------------------------------------------- 1 | La funcion phi de Euler devuelve la cantidad de enteros positivos menores o iguales a n que son coprimos con n (gcd(n, i) = 1) 2 | 3 | // O(sqrt(n)) 4 | ll phi(ll n) { 5 | ll ans = n; 6 | for (int p = 2; p <= n/p; ++p) { 7 | if (n % p == 0) ans -= ans / p; 8 | while (n % p == 0) n /= p; 9 | } 10 | if (n > 1) ans -= ans / n; 11 | return ans; 12 | } 13 | 14 | * Calcular el Euler totient para todos los numeros menores o iguales a MX con Sieve of Eratosthenes. 15 | 16 | const int MX = 1e6; 17 | bool marked[MX+1]; 18 | int phi[MX+1]; 19 | // O(MX log(log(MX))) 20 | void sieve() { 21 | iota(phi, phi+MX+1, 0); 22 | marked[0] = marked[1] = true; 23 | for (int i = 2; i <= MX; i++) { 24 | if (marked[i]) continue; 25 | for (int j = i; j <= MX ; j += i) { 26 | phi[j] -= phi[j] / i; 27 | marked[j] = true; 28 | } 29 | marked[i] = false; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /java [outdated]/Graphs/FloodFill.java: -------------------------------------------------------------------------------- 1 | Dado un grafo implicito como matriz, "colorea" y cuenta el tamaño de las componentes conexas. 2 | Este método debe ser llamado con las coordenadas (i, j) donde se inicia el recorrido, busca cada caracter c1 de la componente, los remplaza por el caracter c2 y retorna el tamaño. 3 | 4 | static final int tam = 1000; // Tamanio maximo de la matriz 5 | static int dy[] = {1, 1, 0,-1,-1,-1, 0, 1}; // Posibles movimientos: 6 | static int dx[] = {0, 1, 1, 1, 0,-1,-1,-1}; // (8 direcciones) 7 | static char grid[][] = new char[tam][tam]; // Matriz de caracteres 8 | static int Y, X; // Tamanio de la matriz 9 | 10 | static int floodfill(int y, int x, char c1, char c2) { 11 | if (y < 0 || y >= Y || x < 0 || x >= X) return 0; 12 | if (grid[y][x] != c1) return 0; 13 | grid[y][x] = c2; 14 | int ans = 1; 15 | for (int i = 0; i < 8; i++) { 16 | ans += floodfill(y + dy[i], x + dx[i], c1, c2); 17 | } 18 | return ans; 19 | } 20 | -------------------------------------------------------------------------------- /c++/Graphs/Bipartite Check.cpp: -------------------------------------------------------------------------------- 1 | Modificacion del BFS para detectar si un grafo es bipartito. 2 | 3 | const int MX = 1e5+5; // Cantidad maxima de nodos 4 | vector g[MX]; // Lista de adyacencia 5 | vector color; // Almacena el color de cada nodo 6 | bool bipartite; // true si el grafo es bipartito 7 | int n, m; // Cantidad de nodos y aristas 8 | 9 | void bfs(int u) { 10 | queue q; 11 | q.push(u); 12 | color[u] = 0; 13 | 14 | while (q.size()) { 15 | u = q.front(); 16 | q.pop(); 17 | for (auto &v : g[u]) { 18 | if (color[v] == -1) { 19 | color[v] = 1-color[u]; 20 | q.push(v); 21 | } else if (color[v] == color[u]) { 22 | bipartite = false; 23 | return; 24 | } 25 | } 26 | } 27 | } 28 | 29 | void init() { 30 | bipartite = true; 31 | color.assign(n, -1); 32 | for (int i = 0; i <= n; i++) { 33 | g[i].clear(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /java [outdated]/Dynamic Programming/Longest increasing subsequence.java: -------------------------------------------------------------------------------- 1 | Halla la longitud de la subsecuencia creciente mas larga. MAX debe definirse en el tamaño limite del array, n es el tamaño del array. Si debe admitir valores repetidos, cambiar el < de I[mid] < values[i] por <= 2 | 3 | static int inf = 2000000000; 4 | static int MAX = 100000; 5 | static int n; 6 | static int values[] = new int[MAX + 5]; 7 | static int L[] = new int[MAX + 5]; 8 | static int I[] = new int[MAX + 5]; 9 | 10 | static int lis() { 11 | int i, low, high, mid; 12 | I[0] = -inf; 13 | for (i = 1; i <= n; i++) I[i] = inf; 14 | int ans = 0; 15 | for (i = 0; i < n; i++) { 16 | low = mid = 0; 17 | high = ans; 18 | while (low <= high) { 19 | mid = (low + high) / 2; 20 | if (I[mid] < values[i]) low = mid + 1; 21 | else high = mid - 1; 22 | } 23 | I[low] = values[i]; 24 | if (ans < low) ans = low; 25 | } 26 | return ans; 27 | } 28 | -------------------------------------------------------------------------------- /c++/Modular arithmetic/Primitive Root.cpp: -------------------------------------------------------------------------------- 1 | g es una raíz primitiva módulo n si y solo si para cualquier entero a tal que gcd(a, n) = 1, existe un entero k tal que: g^k = a mod n. 2 | La raíz primitiva módulo n existe si y solo si: n = 1, 2, 4, o n = p^k, o n = 2 * p^k, donde p es un número primo impar. 3 | Agregar Modular Exponentiation. 4 | 5 | // O(ans * log(phi(p)) * log(p)) 6 | int primitive_root(int p) { // Función para cuando p es primo 7 | vector fact; 8 | int phi = p-1, n = phi; // Si p no es primo, calcular Euler totient de p. 9 | for (int i = 2; i*i <= n; ++i) 10 | if (n%i == 0) { 11 | fact.push_back(i); 12 | while (n%i == 0) n /= i; 13 | } 14 | if (n > 1) fact.push_back(n); 15 | 16 | for (int ans = 2; ans <= p; ++ans) { 17 | bool ok = true; 18 | for (int i = 0; i < fact.size() && ok; ++i) 19 | ok &= expmod(ans, phi / fact[i], p) != 1; 20 | if (ok) return ans; 21 | } 22 | return -1; 23 | } 24 | -------------------------------------------------------------------------------- /c++/Modular arithmetic/Matrix Multiplication.cpp: -------------------------------------------------------------------------------- 1 | Estructura para realizar operaciones de multiplicacion y exponenciacion modular sobre matrices. 2 | 3 | const int mod = 1e9+7; 4 | 5 | struct matrix { 6 | vector> v; 7 | int n, m; 8 | 9 | matrix(int n, int m, bool o = false) : n(n), m(m), v(n, vector(m)) { 10 | if (o) while (n--) v[n][n] = 1; 11 | } 12 | 13 | matrix operator * (const matrix &o) { 14 | matrix ans(n, o.m); 15 | for (int i = 0; i < n; i++) 16 | for (int k = 0; k < m; k++) if (v[i][k]) 17 | for (int j = 0; j < o.m; j++) 18 | ans[i][j] = (1ll*v[i][k]*o.v[k][j] + ans[i][j]) % mod; 19 | return ans; 20 | } 21 | 22 | vector& operator [] (int i) { return v[i]; } 23 | }; 24 | 25 | matrix pow(matrix b, ll e) { 26 | matrix ans(b.n, b.m, true); 27 | while (e) { 28 | if (e&1) ans = ans*b; 29 | b = b*b; 30 | e /= 2; 31 | } 32 | return ans; 33 | } 34 | -------------------------------------------------------------------------------- /c++/Modular arithmetic/Modular Inverse.cpp: -------------------------------------------------------------------------------- 1 | El inverso multiplicativo modular de a % m es un entero b tal que (a*b) % m = 1. Este existe siempre y cuando a y m sean coprimos (gcd(a, m) = 1). 2 | El inverso modular de a se utiliza para calcular (n/a) % m como (n*b) % m. 3 | 4 | * Se puede calcular usando el algoritmo de Euclides extendido. Agregar Extended Euclides. 5 | 6 | // O(log(max(a, m))) 7 | int invmod(int a, int m) { 8 | int d = euclid(a, m); 9 | if (d > 1) return -1; 10 | return (x % m + m) % m; 11 | } 12 | 13 | * Si m es un numero primo, se puede calcular aplicando el pequeño teorema de Fermat. Agregar Modular Exponentiation. 14 | 15 | // O(log(m)) 16 | int invmod(int a, int m) { 17 | return expmod(a, m-2, m); 18 | } 19 | 20 | * Calcular el inverso modulo m para todos los numeros menores o iguales a MX 21 | 22 | const int MX = 1e6; 23 | int inv[MX+1]; 24 | // O(MX) 25 | void invmod(int m) { 26 | inv[1] = 1; 27 | for (int i = 2; i <= MX; i++) 28 | inv[i] = m - ll(m/i) * inv[m%i] % m; 29 | } 30 | -------------------------------------------------------------------------------- /java [outdated]/Graphs/BFS.java: -------------------------------------------------------------------------------- 1 | Búsqueda en anchura sobre grafos. Recibe un nodo inicial u y visita todos los nodos alcanzables desde u. 2 | BFS tambien halla la distancia mas corta entre el nodo inicial u y los demas nodos si todas las aristas tienen peso 1. 3 | 4 | static final int MAX = 100005; // Cantidad maxima de nodos 5 | static ArrayList g[] = new ArrayList[MAX]; // Lista de adyacencia 6 | static long dist[] = new long[MAX]; // Almacena la distancia a cada nodo 7 | static int N, M; // Cantidad de nodos y aristas 8 | 9 | void bfs(int u) { 10 | Queue q = new LinkedList<>(); 11 | q.add(u); 12 | dist[u] = 0; 13 | while (!q.isEmpty()) { 14 | u = q.poll(); 15 | for (int v : g[u]) { 16 | if (dist[v] == -1) { 17 | dist[v] = dist[u] + 1; 18 | q.add(v); 19 | } 20 | } 21 | } 22 | } 23 | 24 | static void init() { 25 | for (int i = 0; i <= N; i++) { 26 | g[i] = new ArrayList<>(); 27 | dist[i] = -1; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /java [outdated]/Graphs/Topological Sort.java: -------------------------------------------------------------------------------- 1 | Dado un grafo acíclico dirigido (DAG), ordena los nodos linealmente de tal manera que si existe una arista entre los nodos u y v entonces u aparece antes que v. 2 | Este ordenamiento es una manera de poner todos los nodos en una línea recta de tal manera que las aristas vayan de izquierda a derecha. 3 | 4 | static final int MAX = 100005; // Cantidad maxima de nodos 5 | static ArrayList g[] = new ArrayList[MAX]; // Lista de adyacencia 6 | static boolean[] vis = new boolean[MAX]; // Marca los nodos ya visitados 7 | static LinkedList topoSort = new LinkedList<>(); // Orden topologico del grafo 8 | static int N, M; // Cantidad de nodos y aristas 9 | 10 | static void dfs(int u) { 11 | vis[u] = true; 12 | for (int v : g[u]) { 13 | if (!vis[v]) dfs(v); 14 | } 15 | topoSort.addFirst(u); 16 | } 17 | 18 | static void init() { 19 | topoSort.clear(); 20 | for (int i = 0; i <= N; i++) { 21 | g[i] = new ArrayList<>(); 22 | vis[i] = false; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /java [outdated]/Strings/Suffix Array String Matching.java: -------------------------------------------------------------------------------- 1 | Busca el string p en el string s (definido en init), y retorna un int[2] con el primer y ultimo indice del suffix array que coinciden con la busqueda. Si no se encuentra, retorna [-1, -1]. Debe inicializarse m con el tamaño de p, y debe ejecutarse previamente suffixArray() de Suffix Array Init.java. 2 | 3 | static String p; 4 | static int m; 5 | 6 | static int[] stringMatching() { 7 | int[] ans = {-1, -1}; 8 | if (m - 1 > n) return ans; 9 | char [] _p = p.toCharArray(); 10 | int l = 0, h = n - 1, c = l; 11 | while (l < h) { 12 | c = (l + h) / 2; 13 | if (strncmp(_s, sa[c], _p) >= 0) h = c; 14 | else l = c + 1; 15 | } 16 | if (strncmp(_s, sa[l], _p) != 0) return ans; 17 | ans[0] = l; 18 | l = 0; h = n - 1; c = l; 19 | while (l < h) { 20 | c = (l + h) / 2; 21 | if (strncmp(_s, sa[c], _p) > 0) h = c; 22 | else l = c + 1; 23 | } 24 | if (strncmp(_s, sa[h], _p) != 0) h--; 25 | ans[1] = h; 26 | return ans; 27 | } 28 | -------------------------------------------------------------------------------- /java [outdated]/Modular arithmetic/Pisano Period.java: -------------------------------------------------------------------------------- 1 | Calcula el Periodo de Pisano de m, que es el periodo con el cual se repite la Sucesión de Fibonacci modulo m. 2 | IMPORTANTE: Si m es primo el algoritmo funciona (considerable) para m < 10^6. Debe agregarse Modular Exponentiation (sin el modulo) y Lowest Common Multiple (para long). 3 | 4 | static long period(long m) { 5 | long a = 0, b = 1, c, pp = 0; 6 | do { 7 | c = (a + b) % m; 8 | a = b; b = c; pp++; 9 | } while (a != 0 || b != 1); 10 | return pp; 11 | } 12 | 13 | static long pisanoPrime(long p, long e) { 14 | return modpow(p, e-1) * period(p); 15 | } 16 | 17 | static long pisanoPeriod(long m) { 18 | long pp = 1; 19 | for (long p = 2; p*p <= m; p++) { 20 | if (m % p == 0) { 21 | long e = 0; 22 | while (m % p == 0) { 23 | e++; 24 | m /= p; 25 | } 26 | pp = lcm(pp, pisanoPrime(p, e)); 27 | } 28 | } 29 | if (m > 1) pp = lcm(pp, period(m)); 30 | return pp; 31 | } 32 | -------------------------------------------------------------------------------- /c++/Graphs/Tarjan.cpp: -------------------------------------------------------------------------------- 1 | Dado un grafo dirigido halla las componentes fuertemente conexas (SCC). 2 | 3 | const int inf = 1e9; 4 | const int MX = 1e5+5; // Cantidad maxima de nodos 5 | vector g[MX]; // Lista de adyacencia 6 | stack st; 7 | int low[MX], pre[MX], cnt; 8 | int comp[MX]; // Almacena la componente a la que pertenece cada nodo 9 | int SCC; // Cantidad de componentes fuertemente conexas 10 | int n, m; // Cantidad de nodos y aristas 11 | 12 | void tarjan(int u) { 13 | low[u] = pre[u] = cnt++; 14 | st.push(u); 15 | for (auto &v : g[u]) { 16 | if (pre[v] == -1) tarjan(v); 17 | low[u] = min(low[u], low[v]); 18 | } 19 | if (low[u] == pre[u]) { 20 | while (true) { 21 | int v = st.top(); st.pop(); 22 | low[v] = inf; 23 | comp[v] = SCC; 24 | if (u == v) break; 25 | } 26 | SCC++; 27 | } 28 | } 29 | 30 | void init() { 31 | cnt = SCC = 0; 32 | for (int i = 0; i <= n; i++) { 33 | g[i].clear(); 34 | pre[i] = -1; // no visitado 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /java [outdated]/Graphs/Bipartite Check.java: -------------------------------------------------------------------------------- 1 | Modificación del BFS para detectar si un grafo es bipartito. 2 | 3 | static final int MAX = 100005; // Cantidad maxima de nodos 4 | static ArrayList g[] = new ArrayList[MAX]; // Lista de adyacencia 5 | static int color[] = new int[MAX]; // Almacena el color de cada nodo 6 | static boolean bipartite; // true si el grafo es bipartito 7 | static int N, M; // Cantidad de nodos y aristas 8 | 9 | void bfs(int u) { 10 | Queue q = new LinkedList<>(); 11 | q.add(u); 12 | color[u] = 0; 13 | while (!q.isEmpty()) { 14 | u = q.poll(); 15 | for (int v : g[u]) { 16 | if (color[v] == -1) { 17 | color[v] = color[u]^1; 18 | q.add(v); 19 | } else if (color[v] == color[u]) { 20 | bipartite = false; 21 | return; 22 | } 23 | } 24 | } 25 | } 26 | 27 | static void init() { 28 | bipartite = true; 29 | for (int i = 0; i <= N; i++) { 30 | g[i] = new ArrayList<>(); 31 | color[i] = -1; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /java [outdated]/Strings/String Hashing.java: -------------------------------------------------------------------------------- 1 | Estructura para realizar operaciones de hashing. 2 | 3 | static long p[] = {257, 359}; 4 | static long mod[] = {1000000007, 1000000009}; 5 | static long X = 1000000010; 6 | 7 | static class Hashing { 8 | long[][] h, pot; 9 | int n; 10 | 11 | public Hashing(String _s) { 12 | char[] s = _s.toCharArray(); 13 | n = s.length; 14 | h = new long[2][n + 1]; 15 | pot = new long[2][n + 1]; 16 | 17 | for (int i = 0; i < 2; ++i) { 18 | pot[i][0] = 1; 19 | } 20 | for (int i = 1; i <= n; ++i) { 21 | for (int j = 0; j < 2; ++j) { 22 | h[j][i] = (h[j][i-1] * p[j] + s[i-1]) % mod[j]; 23 | pot[j][i] = (pot[j][i-1] * p[j]) % mod[j]; 24 | } 25 | } 26 | } 27 | // Hash del substring en el rango [i, j) 28 | long hash(int i, int j) { 29 | long a = (h[0][j] - (h[0][i] * pot[0][j-i] % mod[0]) + mod[0]) % mod[0]; 30 | long b = (h[1][j] - (h[1][i] * pot[1][j-i] % mod[1]) + mod[1]) % mod[1]; 31 | return a*X + b; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /java [outdated]/Modular arithmetic/Modular Inverse.java: -------------------------------------------------------------------------------- 1 | El inverso multiplicativo modular de a % mod es un entero b tal que (a*b) % mod = 1. Éste existe siempre y cuando a y mod sean coprimos (gcd(a, mod) = 1). 2 | El inverso modular de a se utiliza para calcular (n/a) % mod como (n*b) % mod. 3 | 4 | * Se puede calcular usando el algoritmo de Euclides extendido. Agregar Extended Euclides. 5 | 6 | public static long modInverse(int a, int mod) { 7 | long d = extendedEuclid(a, mod); 8 | if (d > 1) { 9 | return -1; 10 | } 11 | return (x % mod + mod) % mod; 12 | } 13 | 14 | * Si mod es un número primo, se puede calcular aplicando el pequeño teorema de Fermat. Agregar Modular Exponentiation. 15 | 16 | public static long modInverse(int a, int mod) { 17 | return modpow(a, mod - 2, mod); 18 | } 19 | 20 | * Calcular el inverso modular para todos los numeros menores a mod. 21 | 22 | static int inv[]; 23 | 24 | public static void modInverse(int mod) { 25 | inv = new int[mod]; 26 | inv[1] = 1; 27 | for (int i = 2; i < mod; i++) { 28 | inv[i] = (mod - (mod / i) * inv[mod % i] % mod) % mod; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /java [outdated]/Dynamic Programming/Max Range 2D.java: -------------------------------------------------------------------------------- 1 | // Cambiar infinito por el mínimo valor posible 2 | static int INF = -100000007; 3 | static int n, m; // filas y columnas 4 | static final int MAX_N = 105, MAX_M = 105; 5 | static int values[][] = new int[MAX_N][MAX_M]; 6 | 7 | static int max_range_sum2D() { 8 | for (int i=0; i0) values[i][j] += values[i-1][j]; 11 | if (j>0) values[i][j] += values[i][j-1]; 12 | if (i>0 && j>0) values[i][j] -= values[i-1][j-1]; 13 | } 14 | } 15 | int max_mat = INF; 16 | for (int i=0; i0) sub_mat -= values[i-1][k]; 22 | if (j>0) sub_mat -= values[h][j-1]; 23 | if (i>0 && j>0) sub_mat += values[i-1][j-1]; 24 | max_mat = Math.max(sub_mat, max_mat); 25 | } 26 | } 27 | } 28 | } 29 | return max_mat; 30 | } 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Grupo de Estudio en Programación Competitiva UFPS 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /c++/Math/Divisors.cpp: -------------------------------------------------------------------------------- 1 | * Calcula la suma de los divisores de n. Agregar Prime Factorization y Modular Exponentiation (sin el modulo). 2 | 3 | ll sumDiv(ll n) { 4 | map f; 5 | fact(n, f); 6 | ll ans = 1; 7 | for (auto p : f) { 8 | ans *= (exp(p.first, p.second+1)-1)/(p.first-1); 9 | } 10 | return ans; 11 | } 12 | 13 | * Calcula la cantidad de divisores de n. Agregar Prime Factorization. 14 | 15 | ll cantDiv(ll n) { 16 | map f; 17 | fact(n, f); 18 | ll ans = 1; 19 | for (auto p : f) ans *= (p.second + 1); 20 | return ans; 21 | } 22 | 23 | * Calcular la cantidad de divisores para todos los numeros menores o iguales a MX con Sieve of Eratosthenes. 24 | 25 | const int MX = 1e6; 26 | bool marked[MX+1]; 27 | vector cnt; 28 | 29 | void sieve() { 30 | cnt.assign(MX+1, 1); 31 | marked[0] = marked[1] = true; 32 | for (int i = 2; i <= MX; i++) { 33 | if (marked[i]) continue; 34 | cnt[i]++; 35 | for (int j = i*2; j <= MX ; j += i) { 36 | int n = j, c = 1; 37 | while (n%i == 0) n /= i, c++; 38 | cnt[j] *= c; 39 | marked[j] = true; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /java [outdated]/Dynamic Programming/Knapsack.java: -------------------------------------------------------------------------------- 1 | Dados N articulos, cada uno con su propio valor y peso y un tamaño maximo de una mochila, se debe calcular el valor maximo de los elementos que es posible llevar. 2 | Debe seleccionarse un subconjunto de objetos, de tal manera que quepan en la mochila y representen el mayor valor posible. 3 | 4 | static int MAX_WEIGHT = 40; // Peso maximo de la mochila 5 | static int MAX_N = 1000; // Numero maximo de objetos 6 | static int N; // Numero de objetos 7 | static int prices[] = new int[MAX_N]; // precios de cada producto 8 | static int weights[] = new int[MAX_N]; // pesos de cada producto 9 | static int memo[][]= new int[MAX_N][MAX_WEIGHT]; // tabla dp 10 | 11 | // El metodo debe llamarse con 0 en el id, y la capacidad de la mochila en w 12 | static int knapsack(int id, int w) { 13 | if (id == N || w == 0) return 0; 14 | if (memo[id][w] != -1) return memo[id][w]; 15 | if (weights[id] > w) memo[id][w] = knapsack(id + 1, w); 16 | else memo[id][w] = Math.max(knapsack(id + 1, w), prices[id] + knapsack(id + 1, w - weights[id])); 17 | return memo[id][w]; 18 | } 19 | // Antes de llamar al metodo, todos los campos de la tabla memo deben iniciarse a -1 20 | -------------------------------------------------------------------------------- /c++/Strings/Palindromic tree.cpp: -------------------------------------------------------------------------------- 1 | const int alfa = 26; 2 | const char L = 'a'; 3 | 4 | struct node { 5 | int next[alfa], link, len; 6 | ll cnt; 7 | node(int x, int l = 0, ll c = 1): len(x), link(l), cnt(c) { 8 | memset(next, 0, sizeof next); 9 | } 10 | int& operator [] (int i) { return next[i]; } 11 | }; 12 | 13 | struct palindromic_tree { 14 | vector tree; 15 | string s; 16 | int n; 17 | int last; 18 | palindromic_tree(string t = "") { 19 | n = last = 0; 20 | tree.pb(node(-1)); 21 | tree.pb(node(0)); 22 | for (auto &c: t)add_char(c); 23 | } 24 | 25 | int getlink(int p) { 26 | while (s[n - tree[p].len - 1] != s[n])p = tree[p].link; 27 | return p; 28 | } 29 | 30 | void add_char(char ch) { 31 | s.pb(ch); 32 | int p = getlink(last), c = ch - L; 33 | if (!tree[p][c]) { 34 | int link = getlink(tree[p].link); 35 | link = max(1, tree[link][c]); 36 | tree[p][c] = SZ(tree); 37 | tree.pb(node(tree[p].len + 2, link, 0)); 38 | } 39 | last = tree[p][c]; 40 | tree[last].cnt++; 41 | n++; 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /java [outdated]/Math/Euler Totient.java: -------------------------------------------------------------------------------- 1 | La función totient de Euler devuelve la cantidad de enteros positivos menores o iguales a n que son coprimos con n (gcd(n, i) = 1) 2 | 3 | * Dado un valor n calcula el Euler totient de n. Debe ejecutarse primero Sieve of Eratosthenes (al menos hasta un numero mayor a la raiz cuadrada de n). 4 | 5 | static long eulerTotient(long n) { 6 | long tot = n; 7 | for (int i = 0, p = primes.get(i); p*p <= n; p = primes.get(++i)) { 8 | if (n % p == 0) { 9 | while (n % p == 0) n /= p; 10 | tot -= tot / p; 11 | } 12 | } 13 | if (n > 1) tot -= tot / n; 14 | return tot; 15 | } 16 | 17 | * Calcular el Euler totient para todos los numeros menores o iguales a MAX. 18 | 19 | static int MAX = 100; 20 | static int[] totient = new int [MAX+1]; 21 | static boolean marked = new boolean[MAX+1]; 22 | 23 | static void eulerTotient() { 24 | marked[1] = 1; 25 | for (int i = 0; i <= MAX; i++) totient[i] = i; 26 | for (int i = 2; i <= MAX; i++) if (!marked[i]) { 27 | for (int j = i; j <= MAX ; j += i) { 28 | totient[j] -= totient[j] / i; 29 | marked[j] = 1; 30 | } 31 | marked[i] = 0; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /java [outdated]/Utilities/Optimized Scanner.java: -------------------------------------------------------------------------------- 1 | Libreria para recibir las entradas; reemplaza el Scanner original, mejorando su eficiencia. 2 | Contiene los metodos next, nextLine y hasNext. Para recibir datos numericos parsear el string leido. 3 | 4 | static class Scanner { 5 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 6 | StringTokenizer st = new StringTokenizer(""); 7 | int spaces = 0; 8 | 9 | public String nextLine() throws IOException { 10 | if (spaces-- > 0) return ""; 11 | else if (st.hasMoreTokens()) return new StringBuilder(st.nextToken("\n")).toString(); 12 | return br.readLine(); 13 | } 14 | 15 | public String next() throws IOException { 16 | spaces = 0; 17 | while (!st.hasMoreTokens()) st = new StringTokenizer(br.readLine()); 18 | return st.nextToken(); 19 | } 20 | 21 | public boolean hasNext() throws IOException { 22 | while (!st.hasMoreTokens()) { 23 | String line = br.readLine(); 24 | if (line == null) return false; 25 | if (line.equals("")) spaces = Math.max(spaces, 0) + 1; 26 | st = new StringTokenizer(line); 27 | } 28 | return true; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /c++/Data structures/Persistent Segment Tree.cpp: -------------------------------------------------------------------------------- 1 | > Guarda el estado del segment tree después de cada actualización para permitir hacer consultas sobre estados pasados. 2 | > Consultas y actualizaciones en O(logn), ocupa O(nlogn) en memoria. 3 | 4 | struct node { 5 | node *left, *right; 6 | int val; 7 | 8 | node() : left(this), right(this), val(0) {} 9 | node(node *left, node *right, int val) : 10 | left(left), right(right), val(val) {} 11 | 12 | node* update(int l, int r, int i, int x) { 13 | if (l == r) return new node(nullptr, nullptr, val + x); 14 | int m = (l + r) / 2; 15 | if (i <= m) 16 | return new node(left->update(l, m, i, x), right, val + x); 17 | return new node(left, right->update(m + 1, r, i, x), val + x); 18 | } 19 | 20 | int query(int l, int r, int i, int j) { 21 | if (i > r || l > j) return 0; 22 | if (i <= l && r <= j) return this->val; 23 | int m = (l + r) / 2; 24 | int lf = left->query(l, m, i, j); 25 | int rg = right->query(m + 1, r, i, j); 26 | return lf + rg; 27 | } 28 | }; 29 | 30 | vector roots = {new node()}; 31 | roots.pb(roots.back()->update(0, n-1, i, x)); 32 | roots[i]->query(0, n-1, l, r); 33 | -------------------------------------------------------------------------------- /c++/Graphs/Prim.cpp: -------------------------------------------------------------------------------- 1 | Dado un grafo halla el costo total de su arbol cobertor minimo. 2 | 3 | struct edge { 4 | int v; ll w; 5 | 6 | bool operator < (const edge &o) const { 7 | return o.w < w; // invertidos para que la pq ordene de < a > 8 | } 9 | }; 10 | 11 | const int MX = 1e5+5; // Cantidad maxima de nodos 12 | vector g[MX]; // Lista de adyacencia 13 | vector vis; // Marca los nodos ya visitados 14 | ll ans; // Costo total del arbol cobertor minimo 15 | int n, m; // Cantidad de nodos y aristas 16 | 17 | void prim() { 18 | priority_queue pq; 19 | vis[0] = true; 20 | for (auto &ed : g[0]) { 21 | int v = ed.v; 22 | if (!vis[v]) pq.push({v, ed.w}); 23 | } 24 | while (pq.size()) { 25 | int u = pq.top().v; 26 | ll w = pq.top().w; 27 | pq.pop(); 28 | if (!vis[u]) { 29 | ans += w; 30 | vis[u] = true; 31 | for (auto &ed : g[u]) { 32 | int v = ed.v; 33 | if (!vis[v]) pq.push({v, ed.w}); 34 | } 35 | } 36 | } 37 | } 38 | 39 | void init() { 40 | ans = 0; 41 | vis.assign(n, false); 42 | for (int i = 0; i <= n; i++) { 43 | g[i].clear(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /java [outdated]/Data Structures/Disjoint Set.java: -------------------------------------------------------------------------------- 1 | Estructura de datos para modelar una colección de conjuntos disyuntos. 2 | Permite determinar de manera eficiente a que conjunto pertenece un elemento, 3 | si dos elementos se encuentran en un mismo conjunto y unir dos conjuntos disyuntos en un uno. 4 | 5 | static class dsu { 6 | int[] par, sz; 7 | int size; // Cantidad de conjuntos 8 | 9 | dsu(int n) { 10 | size = n; 11 | par = new int[n]; 12 | sz = new int[n]; 13 | for (int i = 0; i < n; i++) { 14 | par[i] = i; 15 | sz[i] = 1; 16 | } 17 | } 18 | // Busca el nodo representativo del conjunto de u 19 | int find(int u) { 20 | return par[u] == u ? u : (par[u] = find(par[u])); 21 | } 22 | // Une los conjuntos de u y v 23 | void unite(int u, int v) { 24 | if ((u = find(u)) == (v = find(v))) return; 25 | if (sz[u] > sz[v]) { 26 | int aux = u; 27 | u = v; 28 | v = aux; 29 | } 30 | par[u] = v; 31 | sz[v] += sz[u]; 32 | size--; 33 | } 34 | // Retorna la cantidad de elementos del conjunto de u 35 | int count(int u) { 36 | return sz[find(u)]; 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /c++/Math/Pollard Rho.cpp: -------------------------------------------------------------------------------- 1 | La función Rho de Pollard calcula un divisor no trivial de n. Agregar Modular Multiplication. 2 | 3 | ll rho(ll n) { 4 | if (!(n&1)) return 2; 5 | ll x = 2, y = 2, d = 1; 6 | ll c = rand() % n + 1; 7 | while (d == 1) { 8 | x = (mulmod(x, x, n) + c) % n; 9 | y = (mulmod(y, y, n) + c) % n; 10 | y = (mulmod(y, y, n) + c) % n; 11 | d = __gcd(abs(x-y), n); 12 | } 13 | return d == n ? rho(n) : d; 14 | } 15 | 16 | * Version optimizada 17 | 18 | ll add(ll a, ll b, ll m) { return (a += b) < m ? a : a-m; } 19 | 20 | ll rho(ll n) { 21 | static ll s[MX]; 22 | while (1) { 23 | ll x = rand()%n, y = x, c = rand()%n; 24 | ll *px = s, *py = s, v = 0, p = 1; 25 | while (1) { 26 | *py++ = y = add(mulmod(y, y, n), c, n); 27 | *py++ = y = add(mulmod(y, y, n), c, n); 28 | if ((x = *px++) == y) break; 29 | ll t = p; 30 | p = mulmod(p, abs(y-x), n); 31 | if (!p) return __gcd(t, n); 32 | if (++v == 26) { 33 | if ((p = __gcd(p, n)) > 1 && p < n) return p; 34 | v = 0; 35 | } 36 | } 37 | if (v && (p = __gcd(p, n)) > 1 && p < n) return p; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /java [outdated]/Graphs/LoopCheck.java: -------------------------------------------------------------------------------- 1 | Determina si un Grafo DIRIGIDO tiene o no ciclos. 2 | SE DEBEN LIMPIAR LAS ESTRUCTURAS DE DATOS ANTES DE UTILIZARSE 3 | 4 | static final int MAX = 10010; // Cantidad maxima de nodos 5 | static int v; // Cantidad de Nodos del grafo 6 | static ArrayList ady[] = new ArrayList[MAX]; // Estructura para almacenar el grafo 7 | static int dfs_num[] = new int[MAX]; 8 | static boolean loops; // Bandera de ciclos en el grafo 9 | 10 | /* DFS_NUM STATES 11 | 2 - Explored 12 | 3 - Visited 13 | -1 - Unvisited 14 | 15 | Este metodo debe ser llamado desde un nodo inicial u. 16 | Cortara su ejecucion en el momento que encuentre algun ciclo en el grafo. 17 | */ 18 | static void graphCheck(int u) { 19 | int j, next; 20 | if (loops) return; 21 | dfs_num[u] = 2; 22 | for (j = 0; j < ady[u].size(); j++) { 23 | next = ady[u].get(j); 24 | if (dfs_num[next] == -1) graphCheck(next); 25 | else if (dfs_num[next] == 2) { 26 | loops = true; 27 | break; 28 | } 29 | } 30 | dfs_num[u] = 3; 31 | } 32 | 33 | public static void main(String args[]) { 34 | for (int s = 1; s <= v && !loops; s++) { // Por si el grafo es NO conexo 35 | if (dfs_num[s] == -1) graphCheck(s); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /c++/Graphs/Bellman Ford.cpp: -------------------------------------------------------------------------------- 1 | Dado un grafo con pesos, positivos o negativos, halla la ruta de costo minimo entre un nodo inicial u y todos los demas nodos. 2 | Tambien halla ciclos negativos. 3 | 4 | const ll inf = 1e18; 5 | const int MX = 1e5+5; // Cantidad maxima de nodos 6 | vector g[MX]; // Lista de adyacencia, u->[(v, cost)] 7 | vector dist; // Almacena la distancia a cada nodo 8 | // vector cycle; // Para construir el ciclo negativo 9 | int n, m; // Cantidad de nodos y aristas 10 | 11 | // O(n*m) 12 | void bellmanFord(int src) { 13 | dist.assign(n, inf); 14 | dist[src] = 0; 15 | for (int i = 0; i < n-1; i++) 16 | for (int u = 0; u < n; u++) 17 | if (dist[u] != inf) 18 | for (auto &v : g[u]) { 19 | dist[v.F] = min(dist[v.F], dist[u] + v.S); 20 | } 21 | // Encontrar ciclos negativos 22 | // cycle.clear(); 23 | for (int u = 0; u < n; u++) 24 | if (dist[u] != inf) 25 | for (auto &v : g[u]) 26 | if (dist[v.F] > dist[u] + v.S) { // Ciclo negativo 27 | dist[v.F] = -inf; 28 | // cycle.pb(v.F); // Para reconstruir 29 | } 30 | } 31 | 32 | void init() { 33 | for (int i = 0; i <= n; i++) { 34 | g[i].clear(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /java [outdated]/Graphs/Tarjan.java: -------------------------------------------------------------------------------- 1 | Dado un grafo dirigido halla las componentes fuertemente conexas (SCC). 2 | 3 | static final int MAX = 100005; // Cantidad maxima de nodos 4 | static ArrayList g[] = new ArrayList[MAX]; // Lista de adyacencia 5 | static boolean[] vis = new boolean[MAX]; // Marca los nodos ya visitados 6 | static Stack st = new Stack(); 7 | static int[] low = new int[MAX]; 8 | static int[] num = new int[MAX]; 9 | static int compOf[] = new int[MAX]; // Almacena la componente a la que pertenece cada nodo 10 | static int cantSCC; // Cantidad de componentes fuertemente conexas 11 | static int N, M, cont; // Cantidad de nodos y aristas 12 | 13 | static void tarjan(int u) { 14 | low[u] = num[u] = cont++; 15 | st.push(u); 16 | vis[u] = true; 17 | for (int v : g[u]) { 18 | if (num[v] == -1) 19 | tarjan(v); 20 | if (vis[v]) 21 | low[u] = Math.min(low[u], low[v]); 22 | } 23 | if (low[u] == num[u]) { 24 | while (true) { 25 | int v = st.pop(); 26 | vis[v] = false; 27 | compOf[v] = cantSCC; 28 | if (u == v) break; 29 | } 30 | cantSCC++; 31 | } 32 | } 33 | 34 | static void init() { 35 | cont = cantSCC = 0; 36 | for (int i = 0; i <= N; i++) { 37 | g[i].clear(); 38 | num[i] = -1; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /c++/Math/Simplex integer.cpp: -------------------------------------------------------------------------------- 1 | Resuelve el problema de Linear Integer Programming (LPI). 2 | Agregar Fraction con tipo de dato __int128 y hacer los siguientes ajustes: 3 | 4 | // Cambiar el tipo de dato del Simplex a Fraction 5 | typedef Fraction lf; 6 | 7 | // Agregar constantes 8 | const Fraction ZERO, INF(1e18); 9 | 10 | // Cambiar las siguientes líneas en el Simplex 11 | z = ZERO; // Línea 19 12 | a[x][y] = Fraction(1) / a[x][y]; // Línea 30 13 | if (i != x && a[i][y] != ZERO) { // Línea 32 14 | lf mn = ZERO; // Línea 50 15 | if (a[x][i] < ZERO) { // Línea 56 16 | lf mx = ZERO; // Línea 65 17 | lf mn = INF; // Línea 71 18 | if (a[i][y] > ZERO && b[i] / a[i][y] < mn) // Línea 73 19 | 20 | // Agregar el siguiente método en el Simplex 21 | pair> maximize_int() { 22 | while (true) { 23 | auto sol = maximize(); 24 | bool all_int = true; 25 | for (auto &x : sol.S) all_int &= x.fractional_part() == ZERO; 26 | if (all_int) return sol; 27 | 28 | Fraction nw_b = ZERO; 29 | int id = -1; 30 | for (int i = 0; i < n; i++) { 31 | Fraction fp = b[i].fractional_part(); 32 | if (fp >= nw_b) nw_b = fp, id = i; 33 | } 34 | vector nw_a; 35 | for (auto &x : a[id]) nw_a.pb(-x.fractional_part()); 36 | a.pb(nw_a); 37 | b.pb(-nw_b); 38 | Y.pb(n+m); n++; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /c++/Graphs/Dijkstra.cpp: -------------------------------------------------------------------------------- 1 | Dado un grafo con pesos no negativos halla la ruta de costo minimo entre un nodo inicial u y todos los demas nodos. 2 | 3 | struct edge { 4 | int v; ll w; 5 | bool operator < (const edge &o) const { 6 | return o.w < w; // invertidos para que la pq ordene de < a > 7 | } 8 | }; 9 | 10 | const ll inf = 1e18; 11 | const int MX = 1e5+5; // Cantidad maxima de nodos 12 | vector g[MX]; // Lista de adyacencia 13 | vector vis; // Marca los nodos ya visitados 14 | vector dist; // Almacena la distancia a cada nodo 15 | int pre[MX]; // Almacena el nodo anterior para construir las rutas 16 | int n, m; // Cantidad de nodos y aristas 17 | 18 | void dijkstra(int u) { 19 | priority_queue pq; 20 | pq.push({u, 0}); 21 | dist[u] = 0; 22 | 23 | while (pq.size()) { 24 | u = pq.top().v; pq.pop(); 25 | if (!vis[u]) { 26 | vis[u] = true; 27 | for (auto &ed : g[u]) { 28 | int v = ed.v; 29 | if (!vis[v] && dist[v] > dist[u] + ed.w) { 30 | dist[v] = dist[u] + ed.w; 31 | pre[v] = u; 32 | pq.push({v, dist[v]}); 33 | } 34 | } 35 | } 36 | } 37 | } 38 | 39 | void init() { 40 | vis.assign(n, false); 41 | dist.assign(n, inf); 42 | for (int i = 0; i <= n; i++) { 43 | g[i].clear(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /c++/Data structures/Convex Hull Trick.cpp: -------------------------------------------------------------------------------- 1 | > Agregar líneas en orden no-creciente por pendiente m. Permite consultar el mínimo f(x). Para máximo, cambiar el signo de las lineas: -m, -h. 2 | 3 | typedef ll T; 4 | struct line { T m, h; }; 5 | struct cht { 6 | vector c; 7 | int pos = 0; 8 | 9 | T inter(line a, line b) { 10 | T x = b.h-a.h, y = a.m-b.m; 11 | return x/y + (x%y ? (x>0)==(y>0) : 0); // == ceil(x/y) 12 | } 13 | 14 | void add(T m, T h) { 15 | line l = {m, h}; 16 | if (c.size() && m == c.back().m) { 17 | l.h = min(h, c.back().h); 18 | c.pop_back(); if (pos) pos--; 19 | } 20 | while (c.size() > 1 && inter(c.back(), l) <= inter(c[c.size()-2], c.back())) { 21 | c.pop_back(); if (pos) pos--; 22 | } 23 | c.pb(l); 24 | } 25 | 26 | inline bool fbin(T x, int m) { return inter(c[m], c[m+1]) > x; } 27 | 28 | T query(T x) { 29 | // O(log n) query: 30 | int l = 0, r = c.size(); 31 | while (r-l > 1) { 32 | int m = (l+r)/2; 33 | if (fbin(x, m-1)) r = m; 34 | else l = m; 35 | } 36 | return c[l].m*x + c[l].h; 37 | // O(1) query (para x's ordenadas): 38 | while (pos > 0 && fbin(x, pos-1)) pos--; 39 | while (pos < (int)c.size()-1 && !fbin(x, pos)) pos++; 40 | return c[pos].m*x + c[pos].h; 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /java [outdated]/Graphs/Kruskal.java: -------------------------------------------------------------------------------- 1 | Dado un grafo con pesos halla su árbol cobertor mínimo. 2 | IMPORTANTE: Debe agregarse Disjoint Set. 3 | 4 | static class edge implements Comparable { 5 | int u, v, w; 6 | edge(int _u, int _v, int _w) { 7 | u = _u; 8 | v = _v; 9 | w = _w; 10 | } 11 | 12 | @Override 13 | public int compareTo(edge o) { 14 | if (w > o.w) return 1; 15 | else return -1; 16 | } 17 | } 18 | 19 | static class par { 20 | int F, S; 21 | 22 | par(int f, int s) { 23 | F = f; 24 | S = s; 25 | } 26 | } 27 | 28 | static final int MAX = 100005; // Cantidad maxima de nodos 29 | static ArrayList g[] = new ArrayList[MAX]; // Lista de adyacencia 30 | static ArrayList e = new ArrayList<>(); // Lista de aristas 31 | static int N, M; // Cantidad de nodos y aristas 32 | 33 | static void kruskall() { 34 | Collections.sort(e); 35 | dsu ds = new dsu(N); 36 | int sz = 0; 37 | for (edge ed: e) { 38 | if (ds.find(ed.u) != ds.find(ed.v)) { 39 | ds.unite(ed.u, ed.v); 40 | g[ed.u].add(new par(ed.v, ed.w)); 41 | g[ed.v].add(new par(ed.u, ed.w)); 42 | if (++sz == N - 1) { 43 | break; 44 | } 45 | } 46 | } 47 | } 48 | 49 | static void init() { 50 | e.clear(); 51 | for (int i = 0; i <= N; i++) { 52 | g[i] = new ArrayList<>(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /c++/Network flows/Hungarian.cpp: -------------------------------------------------------------------------------- 1 | Halla el máximo match en un grafo bipartito con pesos (min cost) O(V ^ 3) 2 | 3 | typedef ll T; 4 | const T inf = 1e18; 5 | 6 | struct hung { 7 | int n, m; 8 | vector u, v; vector p, way; 9 | vector> g; 10 | 11 | hung(int n, int m): 12 | n(n), m(m), g(n+1, vector(m+1, inf-1)), 13 | u(n+1), v(m+1), p(m+1), way(m+1) {} 14 | 15 | void set(int u, int v, T w) { g[u+1][v+1] = w; } 16 | 17 | T assign() { 18 | for (int i = 1; i <= n; ++i) { 19 | int j0 = 0; p[0] = i; 20 | vector minv(m+1, inf); 21 | vector used(m+1, false); 22 | do { 23 | used[j0] = true; 24 | int i0 = p[j0], j1; T delta = inf; 25 | for (int j = 1; j <= m; ++j) if (!used[j]) { 26 | T cur = g[i0][j] - u[i0] - v[j]; 27 | if (cur < minv[j]) minv[j] = cur, way[j] = j0; 28 | if (minv[j] < delta) delta = minv[j], j1 = j; 29 | } 30 | for (int j = 0; j <= m; ++j) 31 | if (used[j]) u[p[j]] += delta, v[j] -= delta; 32 | else minv[j] -= delta; 33 | j0 = j1; 34 | } while (p[j0]); 35 | do { 36 | int j1 = way[j0]; p[j0] = p[j1]; j0 = j1; 37 | } while (j0); 38 | } 39 | return -v[0]; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /c++/Strings/Hashing.cpp: -------------------------------------------------------------------------------- 1 | Convierte el string en un polinomio, en O(n), tal que podemos comparar substrings como valores numericos en O(1). 2 | Primero llamar calc_xpow() (una unica vez) con el largo maximo de los strings dados. 3 | 4 | inline int add(int a, int b, const int &mod) { return a+b >= mod ? a+b-mod : a+b; } 5 | inline int sbt(int a, int b, const int &mod) { return a-b < 0 ? a-b+mod : a-b; } 6 | inline int mul(int a, int b, const int &mod) { return 1ll*a*b % mod; } 7 | 8 | const int X[] = {257, 359}; 9 | const int MOD[] = {(int)1e9+7, (int)1e9+9}; 10 | vector xpow[2]; 11 | 12 | struct hashing { 13 | vector h[2]; 14 | 15 | hashing(string &s) { 16 | int n = s.size(); 17 | for (int j = 0; j < 2; ++j) { 18 | h[j].resize(n+1); 19 | for (int i = 1; i <= n; ++i) { 20 | h[j][i] = add(mul(h[j][i-1], X[j], MOD[j]), s[i-1], MOD[j]); 21 | } 22 | } 23 | } 24 | // Hash del substring en el rango [i, j) 25 | ll value(int l, int r) { 26 | int a = sbt(h[0][r], mul(h[0][l], xpow[0][r-l], MOD[0]), MOD[0]); 27 | int b = sbt(h[1][r], mul(h[1][l], xpow[1][r-l], MOD[1]), MOD[1]); 28 | return (ll(a)<<32) + b; 29 | } 30 | }; 31 | 32 | void calc_xpow(int mxlen) { 33 | for (int j = 0; j < 2; ++j) { 34 | xpow[j].resize(mxlen+1, 1); 35 | for (int i = 1; i <= mxlen; ++i) { 36 | xpow[j][i] = mul(xpow[j][i-1], X[j], MOD[j]); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Notebook UFPS - ICPC 2 | 3 | Notebooks oficiales de la Universidad Francisco de Paula Santander en C++ y Java para competencias ICPC. 4 | 5 | Los archivos actuales compilados se encuentran en latex y pdf, en el folder "Notebooks Compilados", mientras que los folders de cada lenguaje contienen los códigos propios del lenguaje. 6 | 7 | Se invita a los estudiantes del semillero a aportar sus propios códigos al notebook, o bien, a indicar temas que consideran deberían ser incluidos mediante issues. 8 | 9 | ### Agradecimientos y créditos: 10 | 11 | - Varios de los algoritmos aquí planteados son implementados/adaptados gracias a los libros y materiales de: 12 | - Antti Laaksonen: [Competitive Programmer's Handbook](https://cses.fi/book/). 13 | - Victor Lecomte: [Handbook Of Geometry For Competitive Programmers](https://vlecomte.github.io/cp-geo.pdf). 14 | - Steven Halim: [Competitive Programming 3](http://cpbook.net/). 15 | - [CP-Algorithms](https://cp-algorithms.com/) (traducción de [MAXimal](http://e-maxx.ru/algo/) a ingles). 16 | - Blogs en [Codeforces](http://codeforces.com/). 17 | - Notebook del equipo "DescomUNAL": [notebook_descomUNAL](https://github.com/ahoraSoyPeor/notebook_descomUNAL). 18 | - Notebook del equipo "UNC - Gracias Demetrio": [icpc-team-notebook-el-vasito](https://github.com/mhunicken/icpc-team-notebook-el-vasito). 19 | - El notebook es generado gracias al [Notebook Generator](https://github.com/pin3da/notebook-generator) de [@pin3da](https://github.com/pin3da/). 20 | -------------------------------------------------------------------------------- /java [outdated]/Graphs/Prim.java: -------------------------------------------------------------------------------- 1 | Dado un grafo halla el costo total de su arbol cobertor mínimo. 2 | 3 | static final int MAX = 100005; // Cantidad maxima de nodos 4 | static ArrayList g[] = new ArrayList[MAX]; // Lista de adyacencia 5 | static boolean[] vis = new boolean[MAX]; // Marca los nodos ya visitados 6 | static long ans; // Costo total del arbol cobertor minimo 7 | static int N, M; // Cantidad de nodos y aristas 8 | 9 | static class edge implements Comparable { 10 | int v; 11 | long w; 12 | 13 | edge(int _v, long _w) { 14 | v = _v; 15 | w = _w; 16 | } 17 | 18 | @Override 19 | public int compareTo(edge o) { 20 | if (w > o.w) return 1; 21 | return -1; 22 | } 23 | } 24 | 25 | static void prim() { 26 | PriorityQueue pq = new PriorityQueue<>(); 27 | vis[0] = true; 28 | for (edge ed : g[0]) { 29 | int v = ed.v; 30 | if (!vis[v]) pq.add(new edge(v, ed.w)); 31 | } 32 | while (!pq.isEmpty()) { 33 | edge ed = pq.poll(); 34 | int u = ed.v; 35 | if (!vis[u]) { 36 | ans += ed.w; 37 | vis[u] = true; 38 | for (edge e : g[u]) { 39 | int v = e.v; 40 | if (!vis[v]) pq.add(new edge(v, e.w)); 41 | } 42 | } 43 | } 44 | } 45 | 46 | static void init() { 47 | ans = 0; 48 | for (int i = 0; i <= N; i++) { 49 | g[i] = new ArrayList(); 50 | vis[i] = false; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /c++/Geometry/line.cpp: -------------------------------------------------------------------------------- 1 | struct line { 2 | pt v; T c; // v:direction c: pos in y axis 3 | line(pt v, T c) : v(v), c(c) {} 4 | line(T a, T b, T c) : v({b, -a}), c(c) {} // ax + by = c 5 | line(pt p, pt q) : v(q-p), c(cross(v, p)) {} 6 | T side(pt p) { return cross(v, p)-c; } 7 | lf dist(pt p) { return abs(side(p)) / abs(v); } 8 | lf sq_dist(pt p) { return side(p)*side(p) / (lf)norm(v); } 9 | line perp_through(pt p) { return {p, p + rot90ccw(v)}; } // line perp to v passing through p 10 | bool cmp_proj(pt p, pt q) { return dot(v, p) < dot(v, q); } // order for points over the line 11 | line translate(pt t) { return {v, c + cross(v, t)}; } 12 | line shift_left(double d) { return {v, c + d*abs(v)}; } 13 | pt proj(pt p) { return p - rot90ccw(v)*side(p)/norm(v); } // pt proyected on the line 14 | pt refl(pt p) { return p - rot90ccw(v)*2*side(p)/norm(v); } // pt reflected on the other side of the line 15 | }; 16 | 17 | bool inter_ll(line l1, line l2, pt &out) { 18 | T d = cross(l1.v, l2.v); 19 | if (d == 0) return false; 20 | out = (l2.v*l1.c - l1.v*l2.c) / d; // floating points 21 | return true; 22 | } 23 | // bisector divides the angle in 2 equal angles 24 | // interior line goes on the same direction as l1 and l2 25 | line bisector(line l1, line l2, bool interior) { 26 | assert(cross(l1.v, l2.v) != 0); // l1 and l2 cannot be parallel! 27 | lf sign = interior ? 1 : -1; 28 | return {l2.v/abs(l2.v) + l1.v/abs(l1.v) * sign, 29 | l2.c/abs(l2.v) + l1.c/abs(l1.v) * sign}; 30 | } 31 | -------------------------------------------------------------------------------- /c++/Dynamic programming/Longest Increasing Subsequence.cpp: -------------------------------------------------------------------------------- 1 | // METODO PARA CALCULAR EL LIS en O(n^2) y O(nlog(n)). La ventaja de tener a mano O(n^2) es porque es mas facil de codear, entender y modificar 2 | 3 | const int MAX = 1e5+1; 4 | int A[MAX]; 5 | int dp[MAX]; 6 | int N = MAX; 7 | vector LIS; // PARA Lis_opt 8 | 9 | // LIS O(n^2).Si es non-decreasing cambiar (i > j) por (i >= j) 10 | int lis() { 11 | int best = -1; 12 | for (int i = 0; i < N; i++) { 13 | dp[i] = 1; 14 | for (int j = 0; j < i; j++) { 15 | if (A[i] > A[j]) dp[i] = max(dp[i], dp[j] + 1); 16 | } 17 | best = max(best, dp[i]); 18 | } 19 | return best; 20 | } 21 | 22 | // LIS O(nlog(n)) Para longest non-decreasing cambiar lower_bound por upper_bound 23 | int lis_opt() { 24 | LIS.clear(); 25 | for (int i = 0; i < N; i++) { 26 | auto id = lower_bound(LIS.begin(), LIS.end(), A[i]); 27 | if (id == LIS.end()) { 28 | LIS.pb(A[i]); 29 | dp[i] = LIS.size(); 30 | } 31 | else { 32 | int idx = id - LIS.begin(); 33 | LIS[idx] = A[i]; 34 | dp[i] = idx + 1; 35 | } 36 | } 37 | return LIS.size(); 38 | } 39 | 40 | // METODO PARA RECONSTRUIR LIS. Para non-decreasing cambiar < por <= 41 | stack rb; 42 | void build() { 43 | int k = LIS.size(); 44 | int cur = oo; 45 | for (int i = N - 1; i >= 0, k; i--) { 46 | if (A[i] < cur && k == dp[i]) { 47 | cur = A[i]; 48 | rb.push(A[i]); 49 | k--; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /c++/Data structures/Sparse table 2D.cpp: -------------------------------------------------------------------------------- 1 | const int MAX_N = 100; 2 | const int MAX_M = 100; 3 | const int KN = log2(MAX_N)+1; 4 | const int KM = log2(MAX_M)+1; 5 | int table[KN][MAX_N][KM][MAX_M]; 6 | int _log2N[MAX_N+1]; 7 | int _log2M[MAX_M+1]; 8 | 9 | int MAT[MAX_N][MAX_M]; 10 | int n, m, ic, ir, jc, jr; 11 | 12 | void calc_log2() { 13 | _log2N[1] = 0; 14 | _log2M[1] = 0; 15 | for (int i = 2; i <= MAX_N; i++) _log2N[i] = _log2N[i/2] + 1; 16 | for (int i = 2; i <= MAX_M; i++) _log2M[i] = _log2M[i/2] + 1; 17 | } 18 | 19 | void build() { 20 | for (ir = 0; ir < n; ir++) { 21 | for (ic = 0; ic < m; ic++) 22 | table[0][ir][0][ic] = MAT[ir][ic]; 23 | for (jc = 1; jc < KM; jc++) 24 | for (ic = 0; ic + (1 <<(jc-1)) < m; ic++) 25 | table[0][ir][jc][ic] = min(table[0][ir][jc-1][ic], table[0][ir][jc-1][ic + (1 << (jc-1))]); 26 | } 27 | 28 | for (jr = 1; jr < KN; jr++) 29 | for (ir = 0; ir < n; ir++) 30 | for (jc = 0; jc < KM; jc++) 31 | for (ic = 0; ic < m; ic++) 32 | table[jr][ir][jc][ic] = min(table[jr-1][ir][jc][ic], table[jr-1][ir+(1<<(jr-1))][jc][ic]); 33 | } 34 | 35 | int rmq(int x1, int y1, int x2, int y2) { 36 | int lenx = x2-x1+1; 37 | int kx = _log2N[lenx]; 38 | int leny = y2-y1+1; 39 | int ky = _log2M[leny]; 40 | 41 | int min_R1 = min(table[kx][x1][ky][y1], table[kx][x1][ky][y2 + 1 - (1< ady[]=new ArrayList [MAX]; 7 | static boolean marked[]=new boolean [MAX]; 8 | static int prev[]=new int [MAX]; 9 | static int dfs_low[]=new int [MAX]; 10 | static int dfs_num[]=new int [MAX]; 11 | static boolean itsmos[]=new int [MAX]; 12 | static ArrayList bridges; 13 | static int dfsRoot, rootChildren, cont; 14 | 15 | /* Recibe el nodo inicial */ 16 | static void dfs(int u) { 17 | dfs_low[u] = dfs_num[u] = cont; 18 | cont++; 19 | marked[u] = true; 20 | int j, v; 21 | 22 | for (j = 0; j < ady[u].size(); j++) { 23 | v = ady[u].get(j); 24 | if (!marked[v]) { 25 | prev[v] = u; 26 | // Caso especial 27 | if (u == dfsRoot) rootChildren++; 28 | dfs(v); 29 | 30 | // Itmos 31 | if (dfs_low[v] >= dfs_num[u]) itsmos[u] = true; 32 | 33 | // Puentes 34 | if (dfs_low[v] > dfs_num[u]) bridges.add(new Edge(Math.min(u, v), Math.max(u, v))); 35 | 36 | dfs_low[u] = Math.min(dfs_low[u], dfs_low[v]); 37 | } else if (v != prev[u]) dfs_low[u] = Math.min(dfs_low[u], dfs_num[v]); 38 | } 39 | } 40 | 41 | public static void main(String args[]) { 42 | dfs(dfsRoot); 43 | /* Caso especial */ 44 | itmos[dfsRoot] = (itmos[dfsRoot] && rootChildren > 1) ? true : false; 45 | } 46 | -------------------------------------------------------------------------------- /c++/Math/Prime Factorization.cpp: -------------------------------------------------------------------------------- 1 | Tres funciones diferentes que guardan en el map f los pares de la descomposicion en factores primos de n. 2 | 3 | 1.1) Iterando hasta sqrt(n) 4 | // O(sqrt(n)) 5 | void fact(ll n, map &f) { 6 | for (int p = 2; 1ll*p*p <= n; p++) 7 | while (n%p == 0) f[p]++, n /= p; 8 | if (n > 1) f[n]++; 9 | } 10 | 11 | 1.2) Version optimizada. Precalcular los primos <= sqrt(n) para iterarlos en el for. 12 | // O(sqrt(n)/log(sqrt(n))) 13 | 14 | 2.1) Utilizando Pollard Rho y Miller Rabin (agregar funciones). 15 | // O(log(n)^3) aprox 16 | void fact(ll n, map &f) { 17 | if (n == 1) return; 18 | if (is_prime(n)) { f[n]++; return; } 19 | ll q = rho(n); 20 | fact(q, f); fact(n/q, f); 21 | } 22 | 23 | 2.2) Version optimizada. Usar Pollard Rho optimizado y sieve() del metodo 3. 24 | 25 | void fact(ll n, map &f) { 26 | for (auto &p : f) while (n%p.F == 0) { p.S++; n /= p.F; } 27 | if (n <= MX) while (n > 1) { f[prime[n]]++; n /= prime[n]; } 28 | else if (is_prime(n)) f[n]++; 29 | else { ll q = rho(n); fact(q, f); fact(n/q, f); } 30 | } 31 | 32 | 3) Precalculando un divisor primo para cada n (solo para n <= 1e6 aprox). 33 | 34 | const int MX = 1e6; 35 | int prime[MX+1]; 36 | 37 | void sieve() { 38 | for (int i = 2; i <= MX; i++) { 39 | if (prime[i]) continue; 40 | for (int j = i; j <= MX; j += i) { 41 | prime[j] = i; 42 | } 43 | } 44 | } 45 | // O(log(n)) 46 | void fact(int n, map &f) { 47 | while (n > 1) { 48 | f[prime[n]]++; 49 | n /= prime[n]; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /c++/Network flows/Dinic.cpp: -------------------------------------------------------------------------------- 1 | Halla el flujo máximo O(E * V ^ 2) 2 | 3 | struct edge { int v, cap, inv, flow; }; 4 | 5 | struct network { 6 | int n, s, t; 7 | vector lvl; 8 | vector> g; 9 | 10 | network(int n) : n(n), lvl(n), g(n) {} 11 | 12 | void add_edge(int u, int v, int c) { 13 | g[u].pb({v, c, (int)g[v].size(), 0}); 14 | g[v].pb({u, 0, (int)g[u].size()-1, c}); 15 | } 16 | 17 | bool bfs() { 18 | fill(lvl.begin(), lvl.end(), -1); 19 | queue q; 20 | lvl[s] = 0; 21 | for (q.push(s); q.size(); q.pop()) { 22 | int u = q.front(); 23 | for (auto &e : g[u]) { 24 | if (e.cap > 0 && lvl[e.v] == -1) { 25 | lvl[e.v] = lvl[u]+1; 26 | q.push(e.v); 27 | } 28 | } 29 | } 30 | return lvl[t] != -1; 31 | } 32 | 33 | int dfs(int u, int nf) { 34 | if (u == t) return nf; 35 | int res = 0; 36 | for (auto &e : g[u]) { 37 | if (e.cap > 0 && lvl[e.v] == lvl[u]+1) { 38 | int tf = dfs(e.v, min(nf, e.cap)); 39 | res += tf; nf -= tf; e.cap -= tf; 40 | g[e.v][e.inv].cap += tf; 41 | g[e.v][e.inv].flow -= tf; 42 | e.flow += tf; 43 | if (nf == 0) return res; 44 | } 45 | } 46 | if (!res) lvl[u] = -1; 47 | return res; 48 | } 49 | 50 | int max_flow(int so, int si, int res = 0) { 51 | s = so; t = si; 52 | while (bfs()) res += dfs(s, INT_MAX); 53 | return res; 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /c++/Geometry/segment.cpp: -------------------------------------------------------------------------------- 1 | bool in_disk(pt a, pt b, pt p) { // pt p inside ab disk 2 | return dot(a-p, b-p) <= 0; 3 | } 4 | bool on_segment(pt a, pt b, pt p) { // p on ab 5 | return orient(a, b, p) == 0 && in_disk(a, b, p); 6 | } 7 | // ab crossing cd 8 | bool proper_inter(pt a, pt b, pt c, pt d, pt &out) { 9 | T oa = orient(c, d, a), 10 | ob = orient(c, d, b), 11 | oc = orient(a, b, c), 12 | od = orient(a, b, d); 13 | // Proper intersection exists iff opposite signs 14 | if (oa*ob < 0 && oc*od < 0) { 15 | out = (a*ob - b*oa) / (ob-oa); 16 | return true; 17 | } 18 | return false; 19 | } 20 | // intersection bwn segments 21 | set inter_ss(pt a, pt b, pt c, pt d) { 22 | pt out; 23 | if (proper_inter(a, b, c, d, out)) return {out}; // if cross -> 1 24 | set s; 25 | if (on_segment(c, d, a)) s.insert(a); // a in cd 26 | if (on_segment(c, d, b)) s.insert(b); // b in cd 27 | if (on_segment(a, b, c)) s.insert(c); // c in ab 28 | if (on_segment(a, b, d)) s.insert(d); // d in ab 29 | return s; // 0, 2 30 | } 31 | lf pt_to_seg(pt a, pt b, pt p) { // p to ab 32 | if (a != b) { 33 | line l(a, b); 34 | if (l.cmp_proj(a, p) && l.cmp_proj(p, b)) // if closest to projection = (a, p, b) 35 | return l.dist(p); // output distance to line 36 | } 37 | return min(abs(p-a), abs(p-b)); // otherwise distance to A or B 38 | } 39 | lf seg_to_seg(pt a, pt b, pt c, pt d) { 40 | pt dummy; 41 | if (proper_inter(a, b, c, d, dummy)) return 0; // ab intersects cd 42 | return min({pt_to_seg(a, b, c), pt_to_seg(a, b, d), pt_to_seg(c, d, a), pt_to_seg(c, d, b)}); // try the 4 pts 43 | } 44 | -------------------------------------------------------------------------------- /c++/Data structures/Dsu on Tree (Sack).cpp: -------------------------------------------------------------------------------- 1 | > Util para responder queries del tipo "cuantos vertices en el subárbol de u cumplen con x propiedad" en O(nlogn * k) para todas las queries. 2 | > Esta implementación permite mantener una única estructura global agregando y quitando información. k es el costo de actualizar esa estructura global. 3 | > Problema de ejemplo: dado un árbol con los nodos coloreados, las consultas son: cuántos nodos del subárbol de u tienen color igual a c. 4 | 5 | const int N = 1e5+5; 6 | vector g[N]; 7 | int sz[N], big[N]; // big[u] = el hijo de u con mayor tamaño 8 | int col[N]; // Del problema de ejemplo 9 | int cnt[N]; // Estructura global del ejemplo 10 | 11 | int pre(int u, int p) { 12 | sz[u] = 1; big[u] = -1; 13 | int mx = 0; 14 | for (auto &v : g[u]) { 15 | if (v != p) { 16 | sz[u] += pre(v, u); 17 | if (sz[v] > mx) mx = sz[v], big[u] = v; 18 | } 19 | } 20 | return sz[u]; 21 | } 22 | 23 | void upd(int u, int p, int x) { 24 | cnt[col[u]] += x; // En el problema de ejemplo k = O(1) 25 | for (auto &v : g[u]) 26 | if (v != p && v != big[u]) 27 | upd(v, u, x); 28 | } 29 | 30 | void dfs(int u, int p, bool keep) { 31 | for (auto &v : g[u]) 32 | if (v != p && v != big[u]) 33 | dfs(v, u, false); 34 | if (big[u] != -1) dfs(big[u], u, true); 35 | // Agregar información del subárbol de los hijos de u != a big[u] 36 | upd(u, p, 1); 37 | // Aqui se responderían las queries 38 | // cnt[c] = cantidad de nodos del subárbol de u con color c 39 | big[u] = -1; 40 | if (!keep) upd(u, p, -1); // Quitar información del subárbol de u 41 | } 42 | -------------------------------------------------------------------------------- /c++/Utilities/Bits Manipulation.cpp: -------------------------------------------------------------------------------- 1 | * Operaciones a nivel de bits. Si n es ll usar 1ll<< en los corrimientos. 2 | 3 | x & 1 -> Verifica si x es impar 4 | x & (1< Verifica si el i-esimo bit esta encendido 5 | x = x | (1< Enciende el i-esimo bit 6 | x = x & ~(1< Apaga el i-esimo bit 7 | x = x ^ (1< Invierte el i-esimo bit 8 | x = ~x -> Invierte todos los bits 9 | x & -x -> Devuelve el bit encendido mas a la derecha (potencia de 2, no el indice) 10 | ~x & (x+1) -> Devuelve el bit apagado mas a la derecha (potencia de 2, no el indice) 11 | x = x | (x+1) -> Enciende el bit apagado mas a la derecha 12 | x = x & (x-1) -> Apaga el bit encendido mas a la derecha 13 | x = x & ~y -> Apaga en x los bits encendidos de y 14 | 15 | * Funciones del compilador gcc. Si n es ll agregar el sufijo ll, por ej: __builtin_clzll(n). 16 | 17 | __builtin_clz(x) -> Cantidad de bits apagados por la izquierda 18 | __builtin_ctz(x) -> Cantidad de bits apagados por la derecha. Indice del bit encendido mas a la derecha 19 | __builtin_popcount(x) -> Cantida de bits encendidos 20 | 21 | * Logaritmo en base 2 (entero). Indice del bit encendido mas a la izquierda. Si x es ll usar 63 y clzll(x). 22 | // O(1) 23 | int lg2(const int &x) { return 31-__builtin_clz(x); } 24 | 25 | * Itera, con indices, los bits encendidos de una mascara. 26 | // O(#bits_encendidos) 27 | for (int x = mask; x; x &= x-1) { 28 | int i = __builtin_ctz(x); 29 | 30 | } 31 | 32 | * Itera todas las submascaras de una mascara. (Iterar todas las submascaras de todas las mascaras es O(3^n)). 33 | // O(2^(#bits_encendidos)) 34 | for (int sub = mask; sub; sub = (sub-1)&mask) { 35 | 36 | } 37 | -------------------------------------------------------------------------------- /java [outdated]/Strings/Suffix Array Init.java: -------------------------------------------------------------------------------- 1 | Crea el suffix array. Deben inicializarse las variables s (String original), N_MAX (Máximo size que puede tener s), y n (Size del string actual). 2 | 3 | static String s; 4 | static int N_MAX = 30; 5 | static int n; 6 | static char _s[]; 7 | static int sa[] = new int[N_MAX]; 8 | static int rk[] = new int[N_MAX]; 9 | static long rk2[] = new long[N_MAX]; 10 | 11 | static List wrapper = new AbstractList() { 12 | @Override 13 | public Integer get(int i) { return sa[i]; } 14 | 15 | @Override 16 | public int size() { return n; } 17 | 18 | @Override 19 | public Integer set(int i, Integer e) { 20 | int v = sa[i]; 21 | sa[i] = e; 22 | return v; 23 | } 24 | }; 25 | 26 | static void suffixArray() { 27 | _s = s.toCharArray(); 28 | for (int i = 0; i < n; i++) { 29 | sa[i] = i; rk[i] = _s[i]; rk2[i] = 0; 30 | } 31 | for (int l = 1; l < n; l <<= 1) { 32 | for (int i = 0; i < n; i++) { 33 | rk2[i] = ((long) rk[i] << 32) + (i + l < n ? rk[i + l] : -1); 34 | } 35 | Collections.sort(wrapper, new Comparator() { 36 | @Override 37 | public int compare(Integer o1, Integer o2) { 38 | if (rk2[o1.intValue()] > rk2[o2.intValue()]) return 1; 39 | else if (rk2[o1.intValue()] == rk2[o2.intValue()]) return 0; 40 | else return -1; 41 | } 42 | }); 43 | for (int i = 0; i < n; i++) { 44 | if (i > 0 && rk2[sa[i]] == rk2[sa[i - 1]]) 45 | rk[sa[i]] = rk[sa[i - 1]]; 46 | else rk[sa[i]] = i; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /c++/Network flows/Stoer Wagner.cpp: -------------------------------------------------------------------------------- 1 | Halla el corte mínimo en un grafo no dirigido y con pesos O(V ^ 3) 2 | 3 | struct stoer_wagner { 4 | int n; 5 | vector> g; 6 | 7 | stoer_wagner(int n) : n(n), g(n, vector(n)) {} 8 | 9 | void add_edge(int a, int b, int w) { 10 | g[a][b] = g[b][a] = w; 11 | } 12 | 13 | pair> min_cut() { 14 | vector used(n); 15 | vector cut, best_cut; 16 | int best_weight = -1; 17 | for (int p = n-1; p >= 0; --p) { 18 | vector w = g[0]; 19 | vector added = used; 20 | int prv, lst = 0; 21 | for (int i = 0; i < p; ++i) { 22 | prv = lst; lst = -1; 23 | for (int j = 1; j < n; ++j) { 24 | if (!added[j] && (lst == -1 || w[j] > w[lst])) lst = j; 25 | } 26 | if (i == p-1) { 27 | for (int j = 0; j < n; j++) 28 | g[prv][j] += g[lst][j]; 29 | for (int j = 0; j < n; j++) 30 | g[j][prv] = g[prv][j]; 31 | used[lst] = true; 32 | cut.pb(lst); 33 | if (best_weight == -1 || w[lst] < best_weight) { 34 | best_cut = cut; 35 | best_weight = w[lst]; 36 | } 37 | } else { 38 | for (int j = 0; j < n; j++) 39 | w[j] += g[lst][j]; 40 | added[lst] = true; 41 | } 42 | } 43 | } 44 | return {best_weight, best_cut}; // best_cut contains all nodes in the same set 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /java [outdated]/Graphs/Dijkstra.java: -------------------------------------------------------------------------------- 1 | Dado un grafo con pesos no negativos halla la ruta de costo mínimo entre un nodo inicial u y todos los demás nodos. 2 | 3 | static long INF = (1l<<62); 4 | static final int MAX = 100005; // Cantidad maxima de nodos 5 | static ArrayList g[] = new ArrayList[MAX]; // Lista de adyacencia 6 | static boolean[] vis = new boolean[MAX]; // Marca los nodos ya visitados 7 | static int pre[] = new int[MAX]; // Almacena el nodo anterior para construir las rutas 8 | static long dist[] = new long[MAX]; // Almacena la distancia a cada nodo 9 | static int N, M; // Cantidad de nodos y aristas 10 | 11 | static class edge implements Comparable { 12 | int v; 13 | long w; 14 | 15 | edge(int _v, long _w) { 16 | v = _v; 17 | w = _w; 18 | } 19 | 20 | @Override 21 | public int compareTo(edge o) { 22 | if (w > o.w) return 1; 23 | else return -1; 24 | } 25 | } 26 | 27 | static void dijkstra(int u) { 28 | PriorityQueue pq = new PriorityQueue<>(); 29 | pq.add(new edge(u, 0)); 30 | dist[u] = 0; 31 | while (!pq.isEmpty()) { 32 | u = pq.poll().v; 33 | if (!vis[u]) { 34 | vis[u] = true; 35 | for (edge nx : g[u]) { 36 | int v = nx.v; 37 | if (!vis[v] && dist[v] > dist[u] + nx.w) { 38 | dist[v] = dist[u] + nx.w; 39 | pre[v] = u; 40 | pq.add(new edge(v, dist[v])); 41 | } 42 | } 43 | } 44 | } 45 | } 46 | 47 | static void init() { 48 | for (int i = 0; i <= N; i++) { 49 | g[i] = new ArrayList<>(); 50 | dist[i] = INF; 51 | vis[i] = false; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /c++/Graphs/2-satisfiability.cpp: -------------------------------------------------------------------------------- 1 | struct sat2 { 2 | int n; 3 | vector>> g; 4 | vector vis, val; 5 | vector comp; 6 | stack st; 7 | 8 | sat2(int n) : n(n), g(2, vector>(2*n)), vis(2*n), val(2*n), comp(2*n) { } 9 | 10 | int neg(int x) { return 2*n-x-1; } 11 | void make_true(int u) { add_edge(neg(u), u); } 12 | void make_false(int u) { make_true(neg(u)); } 13 | void add_or(int u, int v) { implication(neg(u), v); } 14 | void diff(int u, int v) { eq(u, neg(v)); } 15 | void eq(int u, int v) { 16 | implication(u, v); 17 | implication(v, u); 18 | } 19 | void implication(int u, int v) { 20 | add_edge(u, v); 21 | add_edge(neg(v), neg(u)); 22 | } 23 | 24 | void add_edge(int u, int v) { 25 | g[0][u].pb(v); 26 | g[1][v].pb(u); 27 | } 28 | 29 | void dfs(int id, int u, int t = 0) { 30 | vis[u] = true; 31 | for (auto &v : g[id][u]) 32 | if (!vis[v]) dfs(id, v, t); 33 | if (id) comp[u] = t; 34 | else st.push(u); 35 | } 36 | 37 | void kosaraju() { 38 | for (int u = 0; u < n; u++) { 39 | if (!vis[u]) dfs(0, u); 40 | if (!vis[neg(u)]) dfs(0, neg(u)); 41 | } 42 | vis.assign(2*n, false); 43 | int t = 0; 44 | while (!st.empty()) { 45 | int u = st.top(); st.pop(); 46 | if (!vis[u]) dfs(1, u, t++); 47 | } 48 | } 49 | 50 | bool check() { 51 | kosaraju(); 52 | for (int i = 0; i < n; i++) { 53 | if (comp[i] == comp[neg(i)]) return false; 54 | val[i] = comp[i] > comp[neg(i)]; 55 | } 56 | return true; 57 | } 58 | }; 59 | -------------------------------------------------------------------------------- /c++/Data structures/Heavy Light Decomposition.cpp: -------------------------------------------------------------------------------- 1 | > !! Usar build() para inicializar. Para consultas sobre aristas: guardar el valor de cada arista en su nodo hijo y cambiar pos[u] por pos[u]+1 en la linea 55. 2 | > Agregar Segment Tree con un constructor vacío y actualizaciones puntuales. 3 | 4 | typedef int T; // Tipo de dato del segtree 5 | T neutro = 1e9; // "infinito", depende de la operación del segtree 6 | const int N = 1e5+5; 7 | vector g[N]; 8 | int par[N], dep[N], sz[N]; 9 | int pos[N], top[N], value[N]; 10 | vector arr; 11 | int idx; 12 | 13 | int pre(int u, int p, int d) { 14 | par[u] = p; dep[u] = d; 15 | int aux = 1; 16 | for (auto &v : g[u]) { 17 | if (v != p) { 18 | aux += pre(v, u, d+1); 19 | if (sz[v] >= sz[g[u][0]]) swap(v, g[u][0]); 20 | } 21 | } 22 | return sz[u] = aux; 23 | } 24 | 25 | void hld(int u, int p, int t) { 26 | arr[idx] = value[u]; 27 | pos[u] = idx++; 28 | top[u] = t < 0 ? t = u : t; 29 | for (auto &v : g[u]) { 30 | if (v != p) { 31 | hld(v, u, t); 32 | t = -1; 33 | } 34 | } 35 | } 36 | 37 | segtree sgt; 38 | 39 | void build(int n, int root) { 40 | idx = 0; 41 | arr.resize(n); 42 | pre(root, root, 0); 43 | hld(root, root, -1); 44 | sgt = segtree(arr); 45 | } 46 | 47 | T query(int u, int v) { 48 | T ans = neutro; 49 | while (top[u] != top[v]) { 50 | if (dep[top[u]] > dep[top[v]]) swap(u, v); 51 | ans = min(ans, sgt.query(pos[top[v]], pos[v])); 52 | v = par[top[v]]; 53 | } 54 | if (dep[u] > dep[v]) swap(u, v); 55 | ans = min(ans, sgt.query(pos[u], pos[v])); 56 | return ans; 57 | } 58 | 59 | void upd(int u, T val) { 60 | sgt.upd(pos[u], val); 61 | } 62 | -------------------------------------------------------------------------------- /c++/Geometry/halfplanes.cpp: -------------------------------------------------------------------------------- 1 | struct halfplane { 2 | double angle; 3 | pt p, pq; 4 | halfplane() {} 5 | halfplane(pt a, pt b): p(a), pq(b - a) { 6 | angle = atan2(pq.y, pq.x); 7 | } 8 | bool operator < (halfplane b) const { return angle < b.angle; } 9 | bool out(pt q) { return cross(pq, (q-p)) < -eps; } // checks if p is inside the half plane 10 | }; 11 | 12 | const lf inf = 1e100; 13 | // intersection pt of the lines of 2 halfplanes 14 | pt inter(halfplane& h1, halfplane& h2) { 15 | if (abs(cross(unit(h1.pq), unit(h2.pq))) <= eps) return {inf, inf}; 16 | lf alpha = cross((h2.p - h1.p), h2.pq) / cross(h1.pq, h2.pq); 17 | return h1.p + (h1.pq * alpha); 18 | } 19 | 20 | // intersection of halfplanes 21 | vector intersect(vector& b) { 22 | vector box = {{inf, inf}, {-inf, inf}, {-inf, -inf}, {inf, -inf}}; 23 | for (int i = 0; i < 4; i++) { 24 | b.pb({box[i], box[(i + 1) % 4]}); 25 | } 26 | sort(b.begin(), b.end()); 27 | int n = b.size(), q = 1, h = 0; 28 | vector c(n + 10); 29 | for (int i = 0; i < n; i++) { 30 | while (q < h && b[i].out(inter(c[h], c[h-1]))) h--; 31 | while (q < h && b[i].out(inter(c[q], c[q+1]))) q++; 32 | c[++h] = b[i]; 33 | if (q < h && abs(cross(c[h].pq, c[h-1].pq)) < eps) { 34 | if (dot(c[h].pq, c[h-1].pq) <= 0) return {}; 35 | h--; 36 | if (b[i].out(c[h].p)) c[h] = b[i]; 37 | } 38 | } 39 | while (q < h-1 && c[q].out(inter(c[h], c[h-1]))) h--; 40 | while (q < h-1 && c[h].out(inter(c[q], c[q+1]))) q++; 41 | if (h - q <= 1) return {}; 42 | c[h+1] = c[q]; 43 | vector s; 44 | for (int i = q; i < h+1; i++) s.pb(inter(c[i], c[i+1])); 45 | return s; 46 | } 47 | -------------------------------------------------------------------------------- /java [outdated]/Geometry/Convex Hull.java: -------------------------------------------------------------------------------- 1 | Retorna el polígono convexo mas pequeño que cubre (ya sea en el borde o en el interior) un set de puntos. Recibe un vector de puntos, y retorna un vector de puntos indicando el polígono resultante. Es necesario que esten definidos previamente: 2 | 3 | Estructuras: point y vec 4 | Métodos: collinear, euclideanDistance, ccw (de inPolygon) y angle. 5 | 6 | import java.util.ArrayList; 7 | import java.util.Comparator; 8 | import java.util.Collections; 9 | 10 | static ArrayList ConvexHull (ArrayList P) { 11 | int i, j, n = (int)P.size(); 12 | if (n <= 3) { 13 | if (P.get(0).x != P.get(n-1).x || P.get(0).y != P.get(n-1).y) P.add(P.get(0)); 14 | return P; 15 | } 16 | int P0 = 0; 17 | for (i = 1; i < n; i++) 18 | if (P.get(i).y < P.get(P0).y || (P.get(i).y == P.get(P0).y && P.get(i).x > P.get(P0).x)) P0 = i; 19 | Point temp = P.get(0); P.set(0, P.get(P0)); P.set(P0, temp); 20 | Point pivot = P.get(0); 21 | Collections.sort(P, new Comparator() { 22 | public int compare(Point a, Point b) { 23 | if (collinear(pivot, a, b)) return euclideanDistance(pivot, a) < euclideanDistance(pivot, b) ? -1 : 1; 24 | double d1x = a.x - pivot.x, d1y = a.y - pivot.y; 25 | double d2x = b.x - pivot.x, d2y = b.y - pivot.y; 26 | return (Math.atan2(d1y, d1x) - Math.atan2(d2y, d2x)) < 0 ? -1 : 1; 27 | } 28 | }); 29 | ArrayList S = new ArrayList(); 30 | S.add(P.get(n-1)); S.add(P.get(0)); S.add(P.get(1)); 31 | i = 2; 32 | while (i < n) { 33 | j = S.size() - 1; 34 | if (ccw(S.get(j-1), S.get(j), P.get(i))) S.add(P.get(i++)); 35 | else S.remove(S.size() - 1); 36 | } 37 | return S; 38 | } 39 | -------------------------------------------------------------------------------- /java [outdated]/Dynamic Programming/Coin change.java: -------------------------------------------------------------------------------- 1 | Problemas clásicos de moneda con DP 2 | 3 | static final int MAX_COINS = 1005; 4 | static final int MAX_VALUE = 1005; 5 | static final int INF = (int) (2e9); 6 | static int coins[] = new int[MAX_COINS]; 7 | static int dp[] = new int[MAX_VALUE]; 8 | static ArrayList rb = new ArrayList<>(); 9 | 10 | // Calcula el número de formas para valores entre 1 y value. SIN CONTAR PERMUTACIONES 11 | static void ways(int value) { 12 | dp = new int[MAX_VALUE]; 13 | dp[0] = 1; 14 | for (int c: coins) { 15 | for (int i = 1; i <= value; i++) { 16 | if (i - c >= 0) dp[i] += dp[i - c]; 17 | } 18 | } 19 | } 20 | 21 | // Calcula el número de formas para valores entre 1 y value. CONTANDO PERMUTACIONES 22 | static void ways_perm(int value) { 23 | dp = new int[MAX_VALUE]; 24 | dp[0] = 1; 25 | for (int i = 1; i <= value; i++) { 26 | for (int c: coins) { 27 | if (i - c >= 0) dp[i] += dp[i - c]; 28 | } 29 | } 30 | } 31 | 32 | // Calcula el minimo numero de monedas necesarias para los valores entre 1 y value. 33 | static void min_coin(int value) { 34 | dp = new int[MAX_VALUE]; 35 | for (int i = 1; i <= value; i++) { 36 | dp[i] = INF; 37 | for (int c: coins) { 38 | if (i - c >= 0) dp[i] = Math.min(dp[i], dp[i - c] + 1); 39 | } 40 | } 41 | } 42 | 43 | // Guarda en el vector rb las monedas usadas en min_coin. 44 | static void build_ways(int value) { 45 | rb.clear(); 46 | for (int c = MAX_COINS - 1; c >= 0; c--) { 47 | if (value == 0) return; 48 | while (value - coins[c]>= 0 && dp[value] == dp[value - coins[c]] + 1) { 49 | rb.add(coins[c]); 50 | value -= coins[c]; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /c++/Graphs/Lowest Common Ancestor.cpp: -------------------------------------------------------------------------------- 1 | Dados los nodos u y v de un arbol determina cual es el ancestro comun mas bajo entre u y v. 2 | *Tambien puede determinar la arista de peso maximo/minimo entre los nodos u y v (Para esto quitar los "//") 3 | Se debe ejecutar la funcion dfs() primero, el padre de la raiz es sí mismo, w es el valor a almacenar del padre. 4 | 5 | const int N = 4e5+2, inf = 1e9, LOG2 = 20; 6 | int dep[N]; // Profundidad de cada nodo 7 | int par[LOG2][N]; // Sparse table para guardar los padres 8 | // int rmq[LOG2][N]; // Sparse table para guardar pesos 9 | 10 | struct edge { int v, w; }; 11 | vector g[N]; 12 | 13 | void dfs(int u, int p, int d, int w) { 14 | dep[u] = d; 15 | par[0][u] = p; 16 | // rmq[0][u] = w; 17 | for (int j = 1; j < LOG2; j++) { 18 | par[j][u] = par[j-1][par[j-1][u]]; 19 | // rmq[j][u] = max(rmq[j-1][u], rmq[j-1][par[j-1][u]]); 20 | } 21 | for (auto &ed: g[u]) { 22 | int v = ed.v; 23 | int val = ed.w; 24 | if (v == p)continue; 25 | dfs(v, u, d+1, val); 26 | } 27 | } 28 | 29 | int lca(int u, int v) { 30 | // int ans = -1; 31 | if (dep[v] < dep[u])swap(u, v); 32 | int d = dep[v]-dep[u]; 33 | for (int j = LOG2-1; j >= 0; j--) { 34 | if (d >> j & 1) { 35 | // ans = max(ans, rmq[j][v]); 36 | v = par[j][v]; 37 | } 38 | } 39 | // if (u == v) return ans; 40 | if (u == v) return u; 41 | for (int j = LOG2-1; j >= 0; j--) { 42 | if (par[j][u] != par[j][v]) { 43 | // ans = max({ans, rmq[j][u], rmq[j][v]}); 44 | u = par[j][u]; 45 | v = par[j][v]; 46 | } 47 | } 48 | // return max({ans, rmq[1][u], rmq[0][v]}); // si la info es de los nodos 49 | // return max({ans, rmq[0][u], rmq[0][v]}); // si la info es de las aristas 50 | return par[0][u]; 51 | } 52 | -------------------------------------------------------------------------------- /java [outdated]/Math/Gaussian Elimination.java: -------------------------------------------------------------------------------- 1 | Resuelve sistemas de ecuaciones lineales por eliminación Gaussiana. matrix contiene los valores de la matriz cuadrada y result los resultados de las ecuaciones. Retorna un vector con el valor de las n incongnitas. Los resultados pueden necesitar redondeo. 2 | 3 | import java.util.ArrayList; 4 | 5 | static int MAX = 100; 6 | static int n = 3; 7 | static double matrix[][] = new double[MAX][MAX]; 8 | static double result[] = new double[MAX]; 9 | 10 | static ArrayList gauss() { 11 | ArrayList ans = new ArrayList(); 12 | for (int i = 0; i < n; i++) ans.add(0.0); 13 | double temp; 14 | for (int i = 0; i < n; i++) { 15 | int pivot = i; 16 | for (int j = i + 1; j < n; j++) { 17 | temp = Math.abs(matrix[j][i]) - Math.abs(matrix[pivot][i]); 18 | if (temp > 0.000001) pivot = j; 19 | } 20 | double temp2[] = new double[n]; 21 | System.arraycopy(matrix[i], 0, temp2, 0, n); 22 | System.arraycopy(matrix[pivot], 0, matrix[i], 0, n); 23 | System.arraycopy(temp2, 0, matrix[pivot], 0, n); 24 | temp = result[i]; 25 | result[i] = result[pivot]; 26 | result[pivot] = temp; 27 | if (!(Math.abs(matrix[i][i]) < 0.000001)) { 28 | for (int k = i + 1; k < n; k++) { 29 | temp = -matrix[k][i] / matrix[i][i]; 30 | matrix[k][i] = 0; 31 | for (int l = i + 1; l < n; l++) { 32 | matrix[k][l] += matrix[i][l] * temp; 33 | } 34 | result[k] += result[i] * temp; 35 | } 36 | } 37 | } 38 | for (int m = n - 1; m >= 0; m--) { 39 | temp = result[m]; 40 | for (int i = n - 1; i > m; i--) { 41 | temp -= ans.get(i) * matrix[m][i]; 42 | } 43 | ans.set(m, temp / matrix[m][m]); 44 | } 45 | return ans; 46 | } 47 | -------------------------------------------------------------------------------- /c++/Data structures/Segment Tree 2D.cpp: -------------------------------------------------------------------------------- 1 | struct segtree { 2 | int n, m; 3 | T neutro = {1, 0, 0, true}; 4 | vector> st; 5 | 6 | segtree(int &n, int &m, vector> &a) : n(n), m(m) { 7 | st = vector>(2*n, vector(2*m, neutro)); 8 | build(n, m, a); 9 | } 10 | 11 | T get(T a, T b) { 12 | return max(a, b); 13 | } 14 | 15 | void build(int &n, int &m, vector> &a) { 16 | for (int i = 0; i < n; i++) 17 | for (int j = 0; j < m; j++) 18 | st[i + n][j + m] = a[i][j]; 19 | 20 | for (int i = 0; i < n; i++) 21 | for (int j = m - 1; j; j--) 22 | st[i + n][j] = get(st[i + n][j << 1], st[i + n][j << 1 | 1]); 23 | 24 | for (int i = n - 1; i; i--) 25 | for (int j = 0; j < 2*m; j++) 26 | st[i][j] = get(st[i << 1][j], st[i << 1 | 1][j]); 27 | } 28 | 29 | T query(int x1, int y1, int x2, int y2) { 30 | T ans = neutro; 31 | vector pos(2, 0); 32 | int node; 33 | for (x1 += n, x2 += n + 1; x1 < x2; x1 >>= 1, x2 >>= 1) { // rows 34 | node = 0; 35 | if (x1&1) pos[node++] = x1++; 36 | if (x2&1) pos[node++] = --x2; 37 | for (int it = 0; it < node; it++) { 38 | for (int l = y1 + m, r = y2 + m + 1; l < r; l >>= 1, r >>= 1) { // cols 39 | if (l&1) ans = get(ans, st[pos[it]][l++]); 40 | if (r&1) ans = get(ans, st[pos[it]][--r]); 41 | } 42 | } 43 | } 44 | return ans; 45 | } 46 | 47 | void upd(int l, int r, T val) { 48 | st[l + n][r + m] = val; 49 | for (int j = r + m; j; j >>= 1) 50 | st[l][j >> 1] = get(st[l][j], st[l][j + 1]); 51 | 52 | for (int i = l + n; i; i >>= 1) 53 | for (int j = r + m; j; j >>= 1) 54 | st[i >> 1][j] = get(st[i][j], st[i + 1][j]); 55 | } 56 | }; 57 | -------------------------------------------------------------------------------- /java [outdated]/Dynamic Programming/Max Range 3D.java: -------------------------------------------------------------------------------- 1 | // Cambiar valores a, b, c por límites correspondientes 2 | static int a=20, b=20, c=20; 3 | static long acum[][][] = new long [a][b][c]; 4 | static long INF = -10000000000007L; 5 | 6 | static long max_range_3D() { 7 | for (int x=0; x0) acum[x][y][z] += acum[x-1][y][z]; 11 | if (y>0) acum[x][y][z] += acum[x][y-1][z]; 12 | if (z>0) acum[x][y][z] += acum[x][y][z-1]; 13 | if (x>0 && y>0) acum[x][y][z] -= acum[x-1][y-1][z]; 14 | if (x>0 && z>0) acum[x][y][z] -= acum[x-1][y][z-1]; 15 | if (y>0 && z>0) acum[x][y][z] -= acum[x][y-1][z-1]; 16 | if (x>0 && y>0 && z>0) acum[x][y][z] += acum[x-1][y-1][z-1]; 17 | } 18 | } 19 | } 20 | long max_value = INF; 21 | for (int x=0; x0) aux -= acum[x-1][k][l]; 29 | if (y>0) aux -= acum[h][y-1][l]; 30 | if (z>0) aux -= acum[x][k][z-1]; 31 | if (x>0 && y>0) aux += acum[x-1][y-1][l]; 32 | if (x>0 && z>0) aux += acum[x-1][k][z-1]; 33 | if (z>0 && y>0) aux += acum[h][y-1][z-1]; 34 | if (x>0 && y>0 && z>0) aux -= acum[x-1][y-1][z-1]; 35 | max_value = Math.max(max_value, aux); 36 | } 37 | } 38 | } 39 | } 40 | } 41 | } 42 | return max_value; 43 | } 44 | -------------------------------------------------------------------------------- /c++/Strings/Aho Corasick (Trie).cpp: -------------------------------------------------------------------------------- 1 | El trie (o prefix tree) guarda un diccionario de strings como un arbol enraizado. 2 | Aho corasick permite encontrar las ocurrencias de todos los strings del trie en un string s. 3 | 4 | const int alpha = 26; // cantidad de letras del lenguaje 5 | const char L = 'a'; // primera letra del lenguaje 6 | 7 | struct node { 8 | int next[alpha], end; 9 | // int link, exit, cnt; // para aho corasick 10 | int& operator [] (int i) { return next[i]; } 11 | }; 12 | 13 | vector trie = {node()}; 14 | 15 | void add_str(string &s, int id = 1) { 16 | int u = 0; 17 | for (auto ch : s) { 18 | int c = ch-L; 19 | if (!trie[u][c]) { 20 | trie[u][c] = trie.size(); 21 | trie.pb(node()); 22 | } 23 | u = trie[u][c]; 24 | } 25 | trie[u].end = id; // con id > 0 26 | // trie[u].cnt++; // para aho corasick 27 | } 28 | 29 | // aho corasick 30 | void build_ac() { 31 | queue q; q.push(0); 32 | while (q.size()) { 33 | int u = q.front(); q.pop(); 34 | for (int c = 0; c < alpha; ++c) { 35 | int v = trie[u][c]; 36 | if (!v) trie[u][c] = trie[trie[u].link][c]; 37 | else q.push(v); 38 | if (!u || !v) continue; 39 | trie[v].link = trie[trie[u].link][c]; 40 | trie[v].exit = trie[trie[v].link].end ? trie[v].link : trie[trie[v].link].exit; 41 | trie[v].cnt += trie[trie[v].link].cnt; 42 | } 43 | } 44 | } 45 | 46 | vector cnt; // cantidad de ocurrencias en s para cada patron 47 | 48 | void run_ac(string &s) { 49 | int u = 0, sz = s.size(); 50 | for (int i = 0; i < sz; ++i) { 51 | int c = s[i]-L; 52 | while (u && !trie[u][c]) u = trie[u].link; 53 | u = trie[u][c]; 54 | int x = u; 55 | while (x) { 56 | int id = trie[x].end; 57 | if (id) cnt[id-1]++; 58 | x = trie[x].exit; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /c++/Dynamic programming/Traveling Salesman Problem.cpp: -------------------------------------------------------------------------------- 1 | Problema del viajero. Devuelve la ruta minima haciendo un tour visitando todas los nodos (ciudades) una unica vez. 2 | 3 | const int MAX = 18; 4 | int target; // Inicializarlo para (1< rb; 9 | const int INF = (int) (2e9); 10 | 11 | // Llamar para TSP(0, -1) Si no empieza de ninguna ciudad especificia 12 | // De lo contrario llamar TSP(0, 0) 13 | int TSP(int mask, int u) { 14 | if (mask == target) { 15 | return 0; 16 | // O en su defecto el costo extra tras haber visitado todas las ciudades. EJ: Volver a la ciudad principal 17 | } 18 | if (u == -1) { 19 | int ans = INF; 20 | for (int i = 0; i < N; i++) { 21 | ans = min(ans, TSP(mask | (1< trie; 9 | 10 | static class node { 11 | Integer next[]; 12 | boolean fin; 13 | 14 | public node() { 15 | next = new Integer[MAX_L]; 16 | this.fin = false; 17 | } 18 | } 19 | 20 | static void init_trie() { 21 | trie = new ArrayList<>(); 22 | trie.add(new node()); 23 | } 24 | 25 | static void add_str(String s) { 26 | int cur = 0, c; 27 | for (int i = 0; i < s.length(); i++) { 28 | c = s.charAt(i) - L; 29 | if (trie.get(cur).next[c] == null) { 30 | trie.get(cur).next[c] = trie.size(); 31 | trie.add(new node()); 32 | } 33 | cur = trie.get(cur).next[c]; 34 | } 35 | trie.get(cur).fin = true; 36 | } 37 | 38 | static boolean contain(String s) { 39 | int cur = 0, c; 40 | for (int i = 0; i < s.length(); i++) { 41 | c = s.charAt(i) - L; 42 | if (trie.get(cur).next[c] == null) return false; 43 | cur = trie.get(cur).next[c]; 44 | } 45 | return trie.get(cur).fin; 46 | } 47 | 48 | static void dfs(int cur) { 49 | for (int i = 0; i < MAX_L; ++i) { 50 | if (trie.get(cur).next[i] != null) { 51 | // System.out.println((char)(i+L)); 52 | dfs(trie.get(cur).next[i]); 53 | } 54 | } 55 | } 56 | 57 | public static void main(String[] args) { 58 | init_trie(); 59 | String s[] = {"hello", "world", "help"}; 60 | for (String c : s) add_str(c); 61 | } 62 | } 63 | 64 | -------------------------------------------------------------------------------- /c++/Math/Fast Fourier Transform.cpp: -------------------------------------------------------------------------------- 1 | Multiplicacion de polinomios en O(n log n) 2 | 3 | const double PI = acos(-1.0); 4 | 5 | namespace fft { 6 | struct pt { 7 | double r, i; 8 | pt(double r = 0.0, double i = 0.0) : r(r), i(i) {} 9 | pt operator + (const pt &b) { return pt(r+b.r, i+b.i); } 10 | pt operator - (const pt &b) { return pt(r-b.r, i-b.i); } 11 | pt operator * (const pt &b) { return pt(r*b.r - i*b.i, r*b.i + i*b.r); } 12 | }; 13 | vector rev; 14 | 15 | void fft(vector &y, int on) { 16 | int n = y.size(); 17 | for (int i = 1; i < n; i++) 18 | if (i < rev[i]) swap(y[i], y[rev[i]]); 19 | for (int m = 2; m <= n; m <<= 1) { 20 | double ang = -on * 2 * PI / m; 21 | pt wm(cos(ang), sin(ang)); 22 | for (int k = 0; k < n; k += m) { 23 | pt w(1, 0); 24 | for (int j = 0; j < m / 2; j++) { 25 | pt u = y[k + j]; 26 | pt t = w * y[k + j + m / 2]; 27 | y[k + j] = u + t; 28 | y[k + j + m / 2] = u - t; 29 | w = w * wm; 30 | } 31 | } 32 | } 33 | if (on == -1) for (int i = 0; i < n; i++) y[i].r /= n; 34 | } 35 | 36 | vector mul(vector &a, vector &b) { 37 | int n = 1, t = 0, la = a.size(), lb = b.size(); 38 | for (; n <= (la+lb+1); n <<= 1, t++); t = 1<<(t-1); 39 | vector x1(n), x2(n); 40 | rev.assign(n, 0); 41 | for (int i = 0; i < n; i++) rev[i] = rev[i >> 1] >> 1 | (i & 1 ? t : 0); 42 | for (int i = 0; i < la; i++) x1[i] = pt(a[i], 0); 43 | for (int i = 0; i < lb; i++) x2[i] = pt(b[i], 0); 44 | fft(x1, 1); fft(x2, 1); 45 | for (int i = 0; i < n; i++) x1[i] = x1[i] * x2[i]; 46 | fft(x1, -1); 47 | vector ans(n); 48 | for (int i = 0; i < n; i++) ans[i] = x1[i].r + 0.5; 49 | return ans; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /c++/Strings/Suffix Array.cpp: -------------------------------------------------------------------------------- 1 | const int MAXL = 300; 2 | 3 | struct suffixArray { 4 | string s; 5 | int n, MX; 6 | vector ra, tra, sa, tsa, lcp; 7 | 8 | suffixArray(string &_s) { 9 | s = _s+"$"; 10 | n = s.size(); 11 | MX = max(MAXL, n)+2; 12 | ra = tra = sa = tsa = lcp = vector(n); 13 | build(); 14 | } 15 | 16 | void radix_sort(int k) { 17 | vector cnt(MX, 0); 18 | for (int i = 0; i < n; i++) 19 | cnt[(i+k < n) ? ra[i+k]+1 : 1]++; 20 | for (int i = 1; i < MX; i++) 21 | cnt[i] += cnt[i-1]; 22 | for (int i = 0; i < n; i++) 23 | tsa[cnt[(sa[i]+k < n) ? ra[sa[i]+k] : 0]++] = sa[i]; 24 | sa = tsa; 25 | } 26 | 27 | void build() { 28 | for (int i = 0; i < n; i++) 29 | ra[i] = s[i], sa[i] = i; 30 | for (int k = 1, r; k < n; k <<= 1) { 31 | radix_sort(k); 32 | radix_sort(0); 33 | tra[sa[0]] = r = 0; 34 | for (int i = 1; i < n; i++) { 35 | if (ra[sa[i]] != ra[sa[i-1]] || ra[sa[i]+k] != ra[sa[i-1]+k]) ++r; 36 | tra[sa[i]] = r; 37 | } 38 | ra = tra; 39 | if (ra[sa[n-1]] == n-1) break; 40 | } 41 | } 42 | 43 | int& operator [] (int i) { return sa[i]; } 44 | 45 | void build_lcp() { 46 | lcp[0] = 0; 47 | for (int i = 0, k = 0; i < n; i++) { 48 | if (!ra[i]) continue; 49 | while (s[i+k] == s[sa[ra[i]-1]+k]) k++; 50 | lcp[ra[i]] = k; 51 | if (k) k--; 52 | } 53 | } 54 | // Longest Common Substring: construir el suffixArray s = s1 + "#" + s2 + "$" y m = s2.size() 55 | pii lcs() { 56 | int mx = -1, ind = -1; 57 | for (int i = 1; i < n; i++) { 58 | if (((sa[i] < n-m-1) != (sa[i-1] < n-m-1)) && mx < lcp[i]) { 59 | mx = lcp[i]; ind = i; 60 | } 61 | } 62 | return {mx, ind}; 63 | } 64 | }; 65 | -------------------------------------------------------------------------------- /java [outdated]/Dynamic Programming/Traveling Salesman Problem.java: -------------------------------------------------------------------------------- 1 | // Problema del viajero. Devuelve la ruta minima haciendo un tour visitando todas los nodos (ciudades) una unica vez. 2 | 3 | static final int MAX = 18; 4 | static int target; // Inicializarlo para (1< rb = new ArrayList<>(); 9 | static final int INF = (int) (2e9); 10 | 11 | // Llamar para TSP(0, -1) Si no empieza de ninguna ciudad especificia 12 | // De lo contrario llamar TSP(0, 0) 13 | static int TSP(int mask, int u) { 14 | if (mask == target) { 15 | return 0; 16 | // O en su defecto el costo extra tras haber visitado todas las ciudades. EJ: Volver a la ciudad principal 17 | } 18 | if (u == -1) { 19 | int ans = INF; 20 | for (int i = 0; i < N; i++) { 21 | ans = Math.min(ans, TSP(mask | (1< !! Usar build() para inicializar. Problema de ejemplo: dado un árbol, las actualizaciones son marcar nodos, y las consultas son hallar la distancia mínima entre un nodo u y un nodo marcado. 2 | 3 | const int N = 1e5+5; 4 | vector g[N]; 5 | int par[N], dep[N], sz[N]; 6 | map dist[N]; // Distancia entre dos nodos en el árbol original 7 | vector c_ans; // Respuesta optima de cada centroide hacía su subárbol 8 | 9 | int pre(int u, int p) { 10 | sz[u] = 1; 11 | for (auto &v : g[u]) 12 | if (!dep[v] && v != p) 13 | sz[u] += pre(v, u); 14 | return sz[u]; 15 | } 16 | 17 | int centroid(int u, int p, int k) { 18 | for (auto &v : g[u]) 19 | if (!dep[v] && v != p && sz[v] > k) 20 | return centroid(v, u, k); 21 | return u; 22 | } 23 | // Calcular información de cada centroide hacía los nodos de su subárbol 24 | void dfs(int u, int p, int c, int d = 0) { 25 | dist[c][u] = d; // Depende de lo que pida el problema 26 | for (auto &v : g[u]) { 27 | if (!dep[v] && v != p) { 28 | dfs(v, u, c, d+1); 29 | } 30 | } 31 | } 32 | // O(nlogn * k) En este ejemplo k = logn por el mapa dist en el dfs 33 | void build(int u, int p = -1, int d = 1) { 34 | int k = pre(u, p); 35 | int c = centroid(u, p, k/2); 36 | par[c] = p; dep[c] = d; 37 | dfs(c, p, c); 38 | for (auto &v : g[c]) 39 | if (!dep[v]) build(v, c, d+1); 40 | } 41 | // O(logn) lca de u y v en el árbol de centroides 42 | // La ruta de u a v en el árbol original pasa por este lca 43 | int lca(int u, int v) { 44 | for (; u != v; u = par[u]) 45 | if (dep[v] > dep[u]) swap(u, v); 46 | return u; 47 | } 48 | // O((logn)^2) Actualiza la respuesta de los ancestros de u 49 | void upd(int u) { 50 | for (int c = u; c != -1; c = par[c]) { 51 | c_ans[c] = min(c_ans[c], dist[c][u]); 52 | } 53 | } 54 | // O((logn)^2) Combina la respuesta del centroide c + el costo de c a u 55 | int query(int u) { 56 | int mn = N; 57 | for (int c = u; c != -1; c = par[c]) { 58 | mn = min(mn, c_ans[c] + dist[c][u]); 59 | } 60 | return mn; 61 | } 62 | -------------------------------------------------------------------------------- /c++/Data structures/Segment Tree (Lazy Propagation).cpp: -------------------------------------------------------------------------------- 1 | > Dado un vector de valores permite hacer consultas sobre rangos y actualizaciones individuales en O(log n). Construcción en O(n). 2 | > Para hacer actualizaciones sobre rangos se deben descomentar las lineas de Lazy Propagation. 3 | > El valor neutro depende del tipo de consulta. Para sumas: 0, mínimos: infinito, máximos: -infinito, etc. 4 | 5 | typedef int T; // tipo de dato del segtree 6 | struct segtree { 7 | vector st; // , lazy; 8 | int n; T neutro = 1e9; // "infinito" 9 | 10 | segtree(const vector &v) { 11 | n = v.size(); 12 | st.assign(n*4, 0); 13 | // lazy.assign(n*4, neutro); 14 | build(1, 0, n-1, v); 15 | } 16 | 17 | void build(int p, int L, int R, const vector &v) { 18 | if (L == R) st[p] = v[L]; 19 | else { 20 | int m = (L+R)/2, l = p*2, r = l+1; 21 | build(l, L, m, v); 22 | build(r, m+1, R, v); 23 | st[p] = min(st[l], st[r]); 24 | } 25 | } 26 | /* 27 | void propagate(int p, int L, int R, T val) { 28 | if (val == neutro) return; 29 | st[p] = val; 30 | lazy[p] = neutro; 31 | if (L == R) return; 32 | int l = p*2, r = l+1; 33 | lazy[l] = lazy[r] = val; 34 | } 35 | */ 36 | T query(int i, int j) { return query(1, 0, n-1, i, j); } 37 | void upd(int i, int j, T val) { upd(1, 0, n-1, i, j, val); } 38 | 39 | T query(int p, int L, int R, int i, int j) { 40 | // propagate(p, L, R, lazy[p]); 41 | if (i > R || j < L) return neutro; 42 | if (i <= L && j >= R) return st[p]; 43 | int m = (L+R)/2, l = p*2, r = l+1; 44 | T lf = query(l, L, m, i, j); 45 | T rg = query(r, m+1, R, i, j); 46 | return min(lf, rg); 47 | } 48 | 49 | void upd(int p, int L, int R, int i, int j, T val) { 50 | // propagate(p, L, R, lazy[p]); 51 | if (i > R || j < L) return; 52 | if (i <= L && j >= R) st[p] = val; // cambiar por propagate(p, L, R, val); 53 | else { 54 | int m = (L+R)/2, l = p*2, r = l+1; 55 | upd(l, L, m, i, j, val); 56 | upd(r, m+1, R, i, j, val); 57 | st[p] = min(st[l], st[r]); 58 | } 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /java [outdated]/Graphs/Maxflow.java: -------------------------------------------------------------------------------- 1 | Dado un grafo, halla el máximo flujo entre una fuente s y un sumidero t. 2 | SE DEBEN LIMPIAR LAS ESTRUCTURAS DE DATOS ANTES DE UTILIZARSE 3 | 4 | static int n; // Cantidad de nodos del grafo 5 | static ArrayList ady[] = new ArrayList[105]; // lista de Adyacencia 6 | static int capacity[][] = new int[105][105]; // Capacidad de aristas de la red 7 | static int flow[][] = new int[105][105]; // Flujo de cada arista 8 | static int prev[] = new int[105]; 9 | 10 | static void connect(int i, int j, int cap) { 11 | ady[i].add(j); 12 | ady[j].add(i); 13 | capacity[i][j] += cap; 14 | // Si el grafo es dirigido no hacer esta linea 15 | // capacity[j][i] += cap; 16 | } 17 | 18 | static int maxflow(int s, int t, int n) { // s=fuente, t=sumidero, n=numero de nodos 19 | int i, j, maxFlow, u, v, extra, start, end; 20 | for (i = 0; i <= n; i++) { 21 | for (j = 0; j <= n; j++) { 22 | flow[i][j] = 0; 23 | } 24 | } 25 | maxFlow = 0; 26 | while (true) { 27 | for (i = 0; i <= n; i++) prev[i] = -1; 28 | Queue q = new LinkedList(); 29 | q.add(s); 30 | prev[s] = -2; 31 | while (!q.isEmpty()) { 32 | u = q.poll(); 33 | if (u == t) break; 34 | for (j = 0; j < ady[u].size(); j++) { 35 | v = ady[u].get(j); 36 | if (prev[v] == -1 && capacity[u][v] - flow[u][v] > 0) { 37 | q.add(v); 38 | prev[v] = u; 39 | } 40 | } 41 | } 42 | if (prev[t] == -1) break; 43 | extra = Integer.MAX_VALUE; 44 | end = t; 45 | while (end != s) { 46 | start = prev[end]; 47 | extra = Math.min(extra, capacity[start][end]-flow[start][end]); 48 | end = start; 49 | } 50 | end = t; 51 | while (end != s) { 52 | start = prev[end]; 53 | flow[start][end] += extra; 54 | flow[end][start] = -flow[start][end]; 55 | end = start; 56 | } 57 | maxFlow += extra; 58 | } 59 | return maxFlow; 60 | } 61 | 62 | public static void main(String args[]) { 63 | // Para cada arista 64 | connect(s, d, f); // origen, destino, flujo 65 | } 66 | -------------------------------------------------------------------------------- /c++/Math/Fraction.cpp: -------------------------------------------------------------------------------- 1 | Estructura para trabajar con fracciones como un tipo de dato 2 | 3 | typedef ll T; 4 | struct Fraction { 5 | T num, den; 6 | 7 | Fraction() : num(0), den(1) {} 8 | Fraction(T n) : num(n), den(1) {} 9 | Fraction(T n, T d) : num(n), den(d) { reduce(); } 10 | 11 | void reduce() { 12 | assert(den != 0); 13 | T gcd = __gcd(num, den); 14 | num /= gcd, den /= gcd; 15 | if (den < 0) num = -num, den = -den; 16 | } 17 | Fraction fractional_part() const { // x - floor(x) 18 | Fraction fp = Fraction(num % den, den); 19 | if (fp < Fraction(0)) fp += Fraction(1); 20 | return fp; 21 | } 22 | T compare(Fraction f) const { 23 | return num * f.den - den * f.num; 24 | } 25 | Fraction operator + (const Fraction& f) { 26 | return Fraction(num * f.den + den * f.num, den * f.den); 27 | } 28 | Fraction operator - (const Fraction& f) { 29 | return Fraction(num * f.den - den * f.num, den * f.den); 30 | } 31 | Fraction operator * (const Fraction& f) { 32 | Fraction a = Fraction(num, f.den); 33 | Fraction b = Fraction(f.num, den); 34 | return Fraction(a.num * b.num, a.den * b.den); 35 | } 36 | Fraction operator / (const Fraction& f) { 37 | return *this * Fraction(f.den, f.num); 38 | } 39 | Fraction operator += (const Fraction& f) { return *this = *this + f; } 40 | Fraction operator -= (const Fraction& f) { return *this = *this - f; } 41 | Fraction operator *= (const Fraction& f) { return *this = *this * f; } 42 | Fraction operator /= (const Fraction& f) { return *this = *this / f; } 43 | bool operator == (const Fraction& f) const { return compare(f) == 0; } 44 | bool operator != (const Fraction& f) const { return compare(f) != 0; } 45 | bool operator >= (const Fraction& f) const { return compare(f) >= 0; } 46 | bool operator <= (const Fraction& f) const { return compare(f) <= 0; } 47 | bool operator > (const Fraction& f) const { return compare(f) > 0; } 48 | bool operator < (const Fraction& f) const { return compare(f) < 0; } 49 | }; 50 | Fraction operator - (const Fraction& f) { return Fraction(-f.num, f.den); } 51 | ostream& operator << (ostream& os, const Fraction& f) { 52 | return os << "(" << (ll)f.num << "/" << (ll)f.den << ")"; 53 | } 54 | -------------------------------------------------------------------------------- /java [outdated]/Data Structures/RMQ.java: -------------------------------------------------------------------------------- 1 | Estructura de datos que permite procesar consultas por rangos y actualizaciones individuales sobre un arreglo. 2 | Recibe como parametro en el constructor un arreglo de valores. 3 | IMPORTANTE: Para para procesar actualizaciones por rangos se deben descomentar los lineas de Lazy Propagation. 4 | 5 | static class SegmentTree { 6 | int[] st; // , lazy; 7 | int n, neutro = 1 << 30; 8 | 9 | SegmentTree(int[] arr) { 10 | n = arr.length; 11 | st = new int[n << 2]; 12 | // lazy = new int[n << 2]; 13 | // Arrays.fill(lazy, neutro); 14 | build(1, 0, n - 1, arr); 15 | } 16 | 17 | int query(int i, int j) { return query(1, 0, n - 1, i, j); } 18 | void update(int i, int j, int val) { update(1, 0, n - 1, i, j, val); } 19 | 20 | int left(int p) { return p << 1; } 21 | int right(int p) { return (p << 1) | 1; } 22 | 23 | void build(int p, int L, int R, int[] arr) { 24 | if (L == R) st[p] = arr[L]; 25 | else { 26 | int m = (L+R)/2, l = left(p), r = right(p); 27 | build(l, L, m, arr); 28 | build(r, m + 1, R, arr); 29 | st[p] = Math.min(st[l], st[r]); 30 | } 31 | } 32 | /* 33 | void propagate(int p, int L, int R, int val) { 34 | if (val == neutro) return; 35 | st[p] = val; 36 | lazy[p] = neutro; 37 | if (L != R) { 38 | lazy[left(p)] = val; 39 | lazy[right(p)] = val; 40 | } 41 | } 42 | */ 43 | int query(int p, int L, int R, int i, int j) { 44 | // propagate(p, L, R, lazy[p]); 45 | if (i > R || j < L) return neutro; 46 | if (i <= L && j >= R) return st[p]; 47 | int m = (L+R)/2, l = left(p), r = right(p); 48 | l = query(l, L, m, i, j); 49 | r = query(r, m + 1, R, i, j); 50 | return Math.min(l, r); 51 | } 52 | 53 | void update(int p, int L, int R, int i, int j, int val) { 54 | // propagate(p, L, R, lazy[p]); 55 | if (i > R || j < L) return; 56 | if (i <= L && j >= R) st[p] = val; // propagate(p, L, R, val); 57 | else { 58 | int m = (L+R)/2, l = left(p), r = right(p); 59 | update(l, L, m, i, j, val); 60 | update(r, m + 1, R, i, j, val); 61 | st[p] = Math.min(st[l], st[r]); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /c++/Geometry/circle.cpp: -------------------------------------------------------------------------------- 1 | struct circle { 2 | pt c; T r; 3 | }; 4 | // (x-xo)^2 + (y-yo)^2 = r^2 5 | // circle that passes through abc 6 | circle center(pt a, pt b, pt c) { 7 | b = b-a, c = c-a; 8 | assert(cross(b, c) != 0); // no circumcircle if A, B, C aligned 9 | pt cen = a + rot90ccw(b*norm(c) - c*norm(b))/cross(b, c)/2; 10 | return {cen, abs(a-cen)}; 11 | } 12 | // centers of the circles that pass through ab and have radius r 13 | vector centers(pt a, pt b, T r) { 14 | if (abs(a-b) > 2*r + eps) return {}; 15 | pt m = (a+b)/2; 16 | double f = sqrt(r*r/norm(a-m) - 1); 17 | pt c = rot90ccw(a-m)*f; 18 | return {m-c, m+c}; 19 | } 20 | int inter_cl(circle c, line l, pair &out) { 21 | lf h2 = c.r*c.r - l.sq_dist(c.c); 22 | if (h2 >= 0) { // line touches circle 23 | pt p = l.proj(c.c); 24 | pt h = l.v*sqrt(h2)/abs(l.v); // vector of len h parallel to line 25 | out = {p-h, p+h}; 26 | } 27 | return 1 + sign(h2); // if 1 -> out.F == out.S 28 | } 29 | int inter_cc(circle c1, circle c2, pair &out) { 30 | pt d = c2.c-c1.c; 31 | double d2 = norm(d); 32 | if (d2 == 0) { assert(c1.r != c2.r); return 0; } // concentric circles (identical) 33 | double pd = (d2 + c1.r*c1.r - c2.r*c2.r)/2; // = |O_1P| * d 34 | double h2 = c1.r*c1.r - pd*pd/d2; // = h^2 35 | if (h2 >= 0) { 36 | pt p = c1.c + d*pd/d2, h = rot90ccw(d)*sqrt(h2/d2); 37 | out = {p-h, p+h}; 38 | } 39 | return 1 + sign(h2); 40 | } 41 | // circle-line inter = 1 42 | int tangents(circle c1, circle c2, bool inner, vector> &out) { 43 | if (inner) c2.r = -c2.r; // inner tangent 44 | pt d = c2.c-c1.c; 45 | double dr = c1.r-c2.r, d2 = norm(d), h2 = d2-dr*dr; 46 | if (d2 == 0 || h2 < 0) { assert(h2 != 0); return 0; } // (identical) 47 | for (double s : {-1, 1}) { 48 | pt v = (d*dr + rot90ccw(d)*sqrt(h2)*s)/d2; 49 | out.pb({c1.c + v*c1.r, c2.c + v*c2.r}); 50 | } 51 | return 1 + (h2 > 0); // if 1: circle are tangent 52 | } 53 | // circle targent passing through pt p 54 | int tangent_through_pt(pt p, circle c, pair &out) { 55 | double d = abs(p - c.c); 56 | if (d < c.r) return 0; 57 | pt base = c.c-p; 58 | double w = sqrt(norm(base) - c.r*c.r); 59 | pt a = {w, c.r}, b = {w, -c.r}; 60 | pt s = p + base*a/norm(base)*w; 61 | pt t = p + base*b/norm(base)*w; 62 | out = {s, t}; 63 | return 1 + (abs(c.c-p) == c.r); 64 | } 65 | -------------------------------------------------------------------------------- /c++/Values sequences and results/ASCII Table.tex: -------------------------------------------------------------------------------- 1 | Caracteres ASCII con sus respectivos valores numéricos. 2 | 3 | \begin{tabbing} 4 | \textbf{No.}\hspace{1cm} \= \textbf{ASCII}\hspace{2cm} \= \textbf{No.}\hspace{1cm} \= \textbf{ASCII}\hspace{2cm} \\ 5 | 0 \> NUL \> 16 \> DLE \\ 6 | 1 \> SOH \> 17 \> DC1 \\ 7 | 2 \> STX \> 18 \> DC2 \\ 8 | 3 \> ETX \> 19 \> DC3 \\ 9 | 4 \> EOT \> 20 \> DC4 \\ 10 | 5 \> ENQ \> 21 \> NAK \\ 11 | 6 \> ACK \> 22 \> SYN \\ 12 | 7 \> BEL \> 23 \> ETB \\ 13 | 8 \> BS \> 24 \> CAN \\ 14 | 9 \> TAB \> 25 \> EM \\ 15 | 10 \> LF \> 26 \> SUB \\ 16 | 11 \> VT \> 27 \> ESC \\ 17 | 12 \> FF \> 28 \> FS \\ 18 | 13 \> CR \> 29 \> GS \\ 19 | 14 \> SO \> 30 \> RS \\ 20 | 15 \> SI \> 31 \> US \\ 21 | \end{tabbing} 22 | 23 | \begin{tabbing} 24 | \textbf{No.}\hspace{1cm} \= \textbf{ASCII}\hspace{2cm} \= \textbf{No.}\hspace{1cm} \= \textbf{ASCII}\hspace{2cm} \\ 25 | 32 \> (space) \> 48 \> 0 \\ 26 | 33 \> ! \> 49 \> 1 \\ 27 | 34 \> " \> 50 \> 2 \\ 28 | 35 \> \# \> 51 \> 3 \\ 29 | 36 \> \$ \> 52 \> 4 \\ 30 | 37 \> \% \> 53 \> 5 \\ 31 | 38 \> \& \> 54 \> 6 \\ 32 | 39 \> ' \> 55 \> 7 \\ 33 | 40 \> ( \> 56 \> 8 \\ 34 | 41 \> ) \> 57 \> 9 \\ 35 | 42 \> * \> 58 \> : \\ 36 | 43 \> + \> 59 \> ; \\ 37 | 44 \> , \> 60 \> < \\ 38 | 45 \> - \> 61 \> = \\ 39 | 46 \> . \> 62 \> > \\ 40 | 47 \> / \> 63 \> ? \\ 41 | \end{tabbing} 42 | 43 | \begin{tabbing} 44 | \textbf{No.}\hspace{1cm} \= \textbf{ASCII}\hspace{2cm} \= \textbf{No.}\hspace{1cm} \= \textbf{ASCII}\hspace{2cm} \\ 45 | 64 \> @ \> 80 \> P \\ 46 | 65 \> A \> 81 \> Q \\ 47 | 66 \> B \> 82 \> R \\ 48 | 67 \> C \> 83 \> S \\ 49 | 68 \> D \> 84 \> T \\ 50 | 69 \> E \> 85 \> U \\ 51 | 70 \> F \> 86 \> V \\ 52 | 71 \> G \> 87 \> W \\ 53 | 72 \> H \> 88 \> X \\ 54 | 73 \> I \> 89 \> Y \\ 55 | 74 \> J \> 90 \> Z \\ 56 | 75 \> K \> 91 \> [ \\ 57 | 76 \> L \> 92 \> \textbackslash \\ 58 | 77 \> M \> 93 \> ] \\ 59 | 78 \> N \> 94 \> \textasciicircum \\ 60 | 79 \> O \> 95 \> \_ \\ 61 | \end{tabbing} 62 | 63 | \begin{tabbing} 64 | \textbf{No.}\hspace{1cm} \= \textbf{ASCII}\hspace{2cm} \= \textbf{No.}\hspace{1cm} \= \textbf{ASCII}\hspace{2cm} \\ 65 | 96 \> ` \> 112 \> p \\ 66 | 97 \> a \> 113 \> q \\ 67 | 98 \> b \> 114 \> r \\ 68 | 99 \> c \> 115 \> s \\ 69 | 100 \> d \> 116 \> t \\ 70 | 101 \> e \> 117 \> u \\ 71 | 102 \> f \> 118 \> v \\ 72 | 103 \> g \> 119 \> w \\ 73 | 104 \> h \> 120 \> x \\ 74 | 105 \> i \> 121 \> y \\ 75 | 106 \> j \> 122 \> z \\ 76 | 107 \> k \> 123 \> \{ \\ 77 | 108 \> l \> 124 \> \textbar \\ 78 | 109 \> m \> 125 \> \} \\ 79 | 110 \> n \> 126 \> \textasciitilde \\ 80 | 111 \> o \> 127 \> \\ 81 | \end{tabbing} 82 | -------------------------------------------------------------------------------- /java [outdated]/Values sequences and results/ASCII Table.tex: -------------------------------------------------------------------------------- 1 | Caracteres ASCII con sus respectivos valores numéricos. 2 | 3 | 4 | \begin{tabbing} 5 | \textbf{No.}\hspace{1cm} \= \textbf{ASCII}\hspace{2cm} \= \textbf{No.}\hspace{1cm} \= \textbf{ASCII}\hspace{2cm} \\ 6 | 0 \> NUL \> 16 \> DLE \\ 7 | 1 \> SOH \> 17 \> DC1 \\ 8 | 2 \> STX \> 18 \> DC2 \\ 9 | 3 \> ETX \> 19 \> DC3 \\ 10 | 4 \> EOT \> 20 \> DC4 \\ 11 | 5 \> ENQ \> 21 \> NAK \\ 12 | 6 \> ACK \> 22 \> SYN \\ 13 | 7 \> BEL \> 23 \> ETB \\ 14 | 8 \> BS \> 24 \> CAN \\ 15 | 9 \> TAB \> 25 \> EM \\ 16 | 10 \> LF \> 26 \> SUB \\ 17 | 11 \> VT \> 27 \> ESC \\ 18 | 12 \> FF \> 28 \> FS \\ 19 | 13 \> CR \> 29 \> GS \\ 20 | 14 \> SO \> 30 \> RS \\ 21 | 15 \> SI \> 31 \> US \\ 22 | \end{tabbing} 23 | 24 | 25 | \begin{tabbing} 26 | \textbf{No.}\hspace{1cm} \= \textbf{ASCII}\hspace{2cm} \= \textbf{No.}\hspace{1cm} \= \textbf{ASCII}\hspace{2cm} \\ 27 | 32 \> (space) \> 48 \> 0 \\ 28 | 33 \> ! \> 49 \> 1 \\ 29 | 34 \> " \> 50 \> 2 \\ 30 | 35 \> \# \> 51 \> 3 \\ 31 | 36 \> \$ \> 52 \> 4 \\ 32 | 37 \> \% \> 53 \> 5 \\ 33 | 38 \> \& \> 54 \> 6 \\ 34 | 39 \> ' \> 55 \> 7 \\ 35 | 40 \> ( \> 56 \> 8 \\ 36 | 41 \> ) \> 57 \> 9 \\ 37 | 42 \> * \> 58 \> : \\ 38 | 43 \> + \> 59 \> ; \\ 39 | 44 \> , \> 60 \> < \\ 40 | 45 \> - \> 61 \> = \\ 41 | 46 \> . \> 62 \> > \\ 42 | 47 \> / \> 63 \> ? \\ 43 | \end{tabbing} 44 | 45 | \begin{tabbing} 46 | \textbf{No.}\hspace{1cm} \= \textbf{ASCII}\hspace{2cm} \= \textbf{No.}\hspace{1cm} \= \textbf{ASCII}\hspace{2cm} \\ 47 | 64 \> @ \> 80 \> P \\ 48 | 65 \> A \> 81 \> Q \\ 49 | 66 \> B \> 82 \> R \\ 50 | 67 \> C \> 83 \> S \\ 51 | 68 \> D \> 84 \> T \\ 52 | 69 \> E \> 85 \> U \\ 53 | 70 \> F \> 86 \> V \\ 54 | 71 \> G \> 87 \> W \\ 55 | 72 \> H \> 88 \> X \\ 56 | 73 \> I \> 89 \> Y \\ 57 | 74 \> J \> 90 \> Z \\ 58 | 75 \> K \> 91 \> [ \\ 59 | 76 \> L \> 92 \> \textbackslash \\ 60 | 77 \> M \> 93 \> ] \\ 61 | 78 \> N \> 94 \> \textasciicircum \\ 62 | 79 \> O \> 95 \> \_ \\ 63 | \end{tabbing} 64 | 65 | \begin{tabbing} 66 | \textbf{No.}\hspace{1cm} \= \textbf{ASCII}\hspace{2cm} \= \textbf{No.}\hspace{1cm} \= \textbf{ASCII}\hspace{2cm} \\ 67 | 96 \> ` \> 112 \> p \\ 68 | 97 \> a \> 113 \> q \\ 69 | 98 \> b \> 114 \> r \\ 70 | 99 \> c \> 115 \> s \\ 71 | 100 \> d \> 116 \> t \\ 72 | 101 \> e \> 117 \> u \\ 73 | 102 \> f \> 118 \> v \\ 74 | 103 \> g \> 119 \> w \\ 75 | 104 \> h \> 120 \> x \\ 76 | 105 \> i \> 121 \> y \\ 77 | 106 \> j \> 122 \> z \\ 78 | 107 \> k \> 123 \> \{ \\ 79 | 108 \> l \> 124 \> \textbar \\ 80 | 109 \> m \> 125 \> \} \\ 81 | 110 \> n \> 126 \> \textasciitilde \\ 82 | 111 \> o \> 127 \> \\ 83 | \end{tabbing} 84 | -------------------------------------------------------------------------------- /c++/Strings/Suffix Automaton.cpp: -------------------------------------------------------------------------------- 1 | struct suffixAutomaton { 2 | struct node { 3 | int len, link; bool end; 4 | map next; 5 | int fpos, cnt; ll out; 6 | }; 7 | 8 | vector sa; 9 | int last; 10 | ll substrs = 0; 11 | 12 | suffixAutomaton() {} 13 | suffixAutomaton(string &s) { 14 | sa.reserve(s.size()*2); 15 | last = add_node(); 16 | sa[0].link = -1; 17 | for (char &c : s) add_char(c); 18 | for (int p = last; p; p = sa[p].link) sa[p].end = 1; 19 | } 20 | 21 | int add_node() { sa.pb({}); return sa.size()-1; } 22 | 23 | void add_char(char c) { 24 | int u = add_node(), p = last; 25 | sa[u].len = sa[last].len + 1; 26 | sa[u].fpos = sa[u].len - 1; 27 | while (p != -1 && !sa[p].next.count(c)) { 28 | sa[p].next[c] = u; 29 | substrs += p != 0 ? sa[p].len - sa[sa[p].link].len : 1; 30 | p = sa[p].link; 31 | } 32 | if (p != -1) { 33 | int q = sa[p].next[c]; 34 | if (sa[p].len + 1 != sa[q].len) { 35 | int clone = add_node(); 36 | sa[clone] = sa[q]; 37 | sa[clone].len = sa[p].len + 1; 38 | sa[q].link = sa[u].link = clone; 39 | while (p != -1 && sa[p].next[c] == q) { 40 | sa[p].next[c] = clone; 41 | p = sa[p].link; 42 | } 43 | } else sa[u].link = q; 44 | } 45 | last = u; 46 | } 47 | 48 | void run(string &s) { 49 | int u = 0; 50 | for (int i = 0; i < s.size(); ++i) { 51 | while (u && !sa[u].next.count(s[i])) u = sa[u].link; 52 | if (sa[u].next.count(s[i])) u = sa[u].next[s[i]]; 53 | } 54 | } 55 | 56 | int match_str(string &s) { 57 | int u = 0, n = s.size(); 58 | for (int i = 0; i < n; ++i) { 59 | if (!sa[u].next.count(s[i])) return 0; 60 | u = sa[u].next[s[i]]; 61 | } 62 | return count_occ(u); 63 | } 64 | 65 | int count_occ(int u) { 66 | if (sa[u].cnt != 0) return sa[u].cnt; 67 | sa[u].cnt = sa[u].end; 68 | for (auto &v : sa[u].next) 69 | sa[u].cnt += count_occ(v.S); 70 | return sa[u].cnt; 71 | } 72 | 73 | ll count_paths(int u) { 74 | if (sa[u].out != 0) return sa[u].out; 75 | for (auto &v : sa[u].next) 76 | sa[u].out += count_paths(v.S) + 1; 77 | return sa[u].out; 78 | } 79 | 80 | node& operator[](int i) { return sa[i]; } 81 | }; 82 | -------------------------------------------------------------------------------- /c++/Network flows/Maximum Bipartite Matching.cpp: -------------------------------------------------------------------------------- 1 | Halla el maximo match en un grafo bipartito O(|E|*|V|) 2 | 3 | struct mbm { 4 | int l, r; 5 | vector> g; 6 | vector match, vis; 7 | 8 | mbm(int l, int r) : l(l), r(r), g(l) {} 9 | 10 | void add_edge(int l, int r) { 11 | g[l].pb(r); 12 | } 13 | 14 | bool dfs(int u) { 15 | for (auto &v : g[u]) { 16 | if (vis[v]++) continue; 17 | if (match[v] == -1 || dfs(match[v])) { 18 | match[v] = u; 19 | return true; 20 | } 21 | } 22 | return false; 23 | } 24 | 25 | int max_matching() { 26 | int ans = 0; 27 | match.assign(r, -1); 28 | for (int u = 0; u < l; ++u) { 29 | vis.assign(r, 0); 30 | ans += dfs(u); 31 | } 32 | return ans; 33 | } 34 | }; 35 | 36 | Hopcroft Karp: O(E * sqrt(V)) 37 | 38 | const int INF = INT_MAX; 39 | 40 | struct mbm { 41 | vector> g; 42 | vector d, match; 43 | int nil, l, r; 44 | // u -> 0 to l, v -> 0 to r 45 | mbm(int l, int r) : l(l), r(r), nil(l+r), g(l+r), 46 | d(1+l+r, INF), match(l+r, l+r) {} 47 | 48 | void add_edge(int a, int b) { 49 | g[a].pb(l+b); 50 | g[l+b].pb(a); 51 | } 52 | 53 | bool bfs() { 54 | queue q; 55 | for (int u = 0; u < l; u++) { 56 | if (match[u] == nil) { 57 | d[u] = 0; 58 | q.push(u); 59 | } else { 60 | d[u] = INF; 61 | } 62 | } 63 | d[nil] = INF; 64 | while (q.size()) { 65 | int u = q.front(); q.pop(); 66 | if (u == nil) continue; 67 | for (auto v : g[u]) { 68 | if (d[match[v]] == INF) { 69 | d[match[v]] = d[u]+1; 70 | q.push(match[v]); 71 | } 72 | } 73 | } 74 | return d[nil] != INF; 75 | } 76 | 77 | bool dfs(int u) { 78 | if (u == nil) return true; 79 | for (int v : g[u]) { 80 | if (d[match[v]] == d[u]+1 && dfs(match[v])) { 81 | match[v] = u; match[u] = v; 82 | return true; 83 | } 84 | } 85 | d[u] = INF; 86 | return false; 87 | } 88 | 89 | int max_matching() { 90 | int ans = 0; 91 | while (bfs()) { 92 | for (int u = 0; u < l; u++) { 93 | ans += (match[u] == nil && dfs(u)); 94 | } 95 | } 96 | return ans; 97 | } 98 | }; 99 | -------------------------------------------------------------------------------- /c++/Math/Gauss Jordan.cpp: -------------------------------------------------------------------------------- 1 | Algoritmo de eliminación Gauss-Jordan O(N ^ 3) 2 | Soluciona un sistema de ecuaciones de la forma: 3 | a11 x1 + a12 x2 + ... + a1m xm = b1 4 | a21 x1 + a22 x2 + ... + a2m xm = b2 5 | an x1 + an2 x2 + ... + anm xm = bn 6 | 7 | El vector a contiene los valores de la matriz, cada fila es una ecuación, la última columna contiene los valores b. 8 | 9 | const int EPS = 1; 10 | int gauss(vector>& a, vector &ans) { 11 | int n = a.size(), m = a[0].size()-1; 12 | vector where(m, -1); 13 | for (int col = 0, row = 0; col < m && row < n; ++col) { 14 | int sel = row; 15 | for (int i = row; i < n; ++i) 16 | if (abs(a[i][col]) > abs(a[sel][col])) sel = i; 17 | if (abs(a[sel][col]) < EPS) continue; 18 | swap(a[sel], a[row]); 19 | where[col] = row; 20 | for (int i = 0; i < n; ++i) 21 | if (i != row) { 22 | int c = divide(a[i][col], a[row][col]); 23 | for (int j = col; j <= m; ++j) 24 | a[i][j] = sub(a[i][j], mul(a[row][j], c)); 25 | } 26 | ++row; 27 | } 28 | ans.assign(m, 0); 29 | for (int i = 0; i < m; ++i) 30 | if (where[i] != -1) ans[i] = divide(a[where[i]][m], a[where[i]][i]); 31 | for (int i = 0; i < n; ++i) { 32 | int sum = 0; 33 | for (int j = 0; j < m; ++j) 34 | sum = add(sum, mul(ans[j], a[i][j])); 35 | if (sum != a[i][m]) return 0; 36 | } 37 | for (int i = 0; i < m; ++i) 38 | if (where[i] == -1) return -1; 39 | return 1; 40 | } 41 | 42 | 43 | Gauss jordan para operaciones de xor 44 | 45 | int gauss(vector> &a, vector> &b, int n, int m, vector> &ans) { 46 | vector where(m, -1); 47 | for (int col = 0, row = 0; col < m && row < n; ++col) { 48 | for (int i = row; i < n; ++i) { 49 | if (a[i][col]) { 50 | swap(a[i], a[row]); 51 | swap(b[i], b[row]); 52 | break; 53 | } 54 | } 55 | if (!a[row][col])continue; 56 | where[col] = row; 57 | for (int i = 0; i < n; ++i) 58 | if (i != row && a[i][col]) { 59 | a[i] ^= a[row]; 60 | b[i] ^= b[row]; 61 | } 62 | ++row; 63 | } 64 | ans.assign(m, 0); 65 | for (int i = 0; i < m; ++i) 66 | if (where[i] != -1) ans[i] = b[where[i]]; 67 | for (int i = 0; i < n; ++i) { 68 | if (ans[i] == 0) return 0; 69 | } 70 | for (int i = 0; i < m; ++i) 71 | if (where[i] == -1) return -1; // infinite solutions 72 | return 1; 73 | } 74 | -------------------------------------------------------------------------------- /c++/Network flows/Weighted matching.cpp: -------------------------------------------------------------------------------- 1 | Halla el máximo match con pesos O(V ^ 3) 2 | 3 | typedef int type; 4 | struct matching_weighted { 5 | int l, r; 6 | vector> c; 7 | matching_weighted(int l, int r) : l(l), r(r), c(l, vector(r)) { 8 | assert(l <= r); 9 | } 10 | 11 | void add_edge(int a, int b, type cost) { c[a][b] = cost; } 12 | 13 | type matching() { 14 | vector v(r), d(r); // v: potential 15 | vector ml(l, -1), mr(r, -1); // matching pairs 16 | vector idx(r), prev(r); 17 | iota(idx.begin(), idx.end(), 0); 18 | auto residue = [&](int i, int j) { return c[i][j]-v[j]; }; 19 | for (int f = 0; f < l; ++f) { 20 | for (int j = 0; j < r; ++j) { 21 | d[j] = residue(f, j); 22 | prev[j] = f; 23 | } 24 | type w; 25 | int j, l; 26 | for (int s = 0, t = 0;;) { 27 | if (s == t) { 28 | l = s; 29 | w = d[idx[t++]]; 30 | for (int k = t; k < r; ++k) { 31 | j = idx[k]; 32 | type h = d[j]; 33 | if (h <= w) { 34 | if (h < w) t = s, w = h; 35 | idx[k] = idx[t]; 36 | idx[t++] = j; 37 | } 38 | } 39 | for (int k = s; k < t; ++k) { 40 | j = idx[k]; 41 | if (mr[j] < 0) goto aug; 42 | } 43 | } 44 | int q = idx[s++], i = mr[q]; 45 | for (int k = t; k < r; ++k) { 46 | j = idx[k]; 47 | type h = residue(i, j) - residue(i, q) + w; 48 | if (h < d[j]) { 49 | d[j] = h; 50 | prev[j] = i; 51 | if (h == w) { 52 | if (mr[j] < 0) goto aug; 53 | idx[k] = idx[t]; 54 | idx[t++] = j; 55 | } 56 | } 57 | } 58 | } 59 | aug: 60 | for (int k = 0; k < l; ++k) 61 | v[idx[k]] += d[idx[k]] - w; 62 | int i; 63 | do { 64 | mr[j] = i = prev[j]; 65 | swap(j, ml[i]); 66 | } while (i != f); 67 | } 68 | type opt = 0; 69 | for (int i = 0; i < l; ++i) 70 | opt += c[i][ml[i]]; // (i, ml[i]) is a solution 71 | return opt; 72 | } 73 | }; 74 | -------------------------------------------------------------------------------- /java [outdated]/Graphs/Lowest Common Ancestor.java: -------------------------------------------------------------------------------- 1 | Dados los nodos u y v de un arbol determina cual es el ancestro comun mas bajo entre u y v. 2 | *Tambien puede determinar la arista de peso maximo entre los nodos u y v (Para esto quitar los "// ") 3 | SE DEBE EJECUTAR EL METODO build() ANTES DE UTILIZARSE 4 | 5 | static final int MAX = 100005; // Cantidad maxima de nodos 6 | static final int LOG2 = 17; // log2(MAX)+1 7 | // ArrayList g[] = new ArrayList[MAX]; // Lista de adyacencia 8 | static ArrayList g[] = new ArrayList[MAX]; // Lista de adyacencia 9 | static int dep[] = new int[MAX]; // Almacena la profundidad de cada nodo 10 | static int par[][] = new int[MAX][LOG2]; // Almacena los padres para responder las consultas 11 | // int rmq[][] = new int[MAX][LOG2]; // Almacena los pesos para responder las consultas 12 | static int N, M; // Cantidad de nodos y aristas 13 | 14 | /*static class edge { 15 | int v, w; 16 | 17 | edge(int _v, int _w) { 18 | v = _v; 19 | w = _w; 20 | } 21 | };*/ 22 | 23 | static int lca(int u, int v) { 24 | // int ans = -1; 25 | if (dep[u] < dep[v]) { 26 | int aux = u; 27 | u = v; 28 | v = aux; 29 | } 30 | int diff = dep[u] - dep[v]; 31 | for (int i = LOG2-1; i >= 0; i--) { 32 | if ((diff & (1 << i))> 0) { 33 | // ans = Math.max(ans, rmq[u][i]); 34 | u = par[u][i]; 35 | } 36 | } 37 | // if (u == v) return ans; 38 | if (u == v) return u; 39 | for (int i = LOG2-1; i >= 0; i--) { 40 | if (par[u][i] != par[v][i]) { 41 | // ans = Math.max(ans, Math.max(rmq[u][i], rmq[v][i])); 42 | u = par[u][i]; 43 | v = par[v][i]; 44 | } 45 | } 46 | // return Math.max(ans, Math.max(rmq[u][0], rmq[v][0])); 47 | return par[u][0]; 48 | } 49 | 50 | static void dfs(int u, int p, int d) { 51 | dep[u] = d; 52 | par[u][0] = p; 53 | for (int v /* edge ed*/ : g[u]) { 54 | // int v = ed.v; 55 | if (v != p) { 56 | // rmq[v][0] = ed.w; 57 | dfs(v, u, d + 1); 58 | } 59 | } 60 | } 61 | 62 | static void build() { 63 | for (int i = 0; i < N; i++) dep[i] = -1; 64 | for (int i = 0; i < N; i++) { 65 | if (dep[i] == -1) { 66 | // rmq[i][0] = -1; 67 | dfs(i, i, 0); 68 | } 69 | } 70 | for (int j = 0; j < LOG2-1; j++) { 71 | for (int i = 0; i < N; i++) { 72 | par[i][j+1] = par[par[i][j]][j]; 73 | // rmq[i][j+1] = Math.max(rmq[par[i][j]][j], rmq[i][j]); 74 | } 75 | } 76 | } 77 | 78 | static void init() { 79 | for (int i = 0; i <= N; i++) { 80 | g[i] = new ArrayList<>(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /c++/Math/Simplex.cpp: -------------------------------------------------------------------------------- 1 | Maximizar la ecuación x1 + x2 + x3 ... 2 | sujeta a restricciones x1 + x2 <= 2, x2 + x3 <= 5 ... 3 | A: matriz de ecuaciones, contiene los coeficientes de cada variable 4 | B: vector con los coeficientes de las restricciones 5 | C: costos de las variables 6 | 7 | const double EPS = 1e-6; 8 | 9 | typedef double lf; 10 | struct simplex { 11 | vector X, Y; 12 | vector> a; 13 | vector b, c; 14 | lf z; 15 | int n, m; 16 | 17 | simplex(vector> &A, vector &B, vector &C) { 18 | a = A; b = B; c = C; 19 | n = b.size(); m = c.size(); z = 0.0; 20 | X.resize(m); iota(X.begin(), X.end(), 0); 21 | Y.resize(n); iota(Y.begin(), Y.end(), m); 22 | } 23 | 24 | void pivot(int x, int y) { 25 | swap(X[y], Y[x]); 26 | b[x] /= a[x][y]; 27 | for (int i = 0; i < m; i++) { 28 | if (i != y) a[x][i] /= a[x][y]; 29 | } 30 | a[x][y] = 1 / a[x][y]; 31 | for (int i = 0; i < n; i++) { 32 | if (i != x && abs(a[i][y]) > EPS) { 33 | b[i] -= a[i][y] * b[x]; 34 | for (int j = 0; j < m; j++) { 35 | if (j != y) a[i][j] -= a[i][y] * a[x][j]; 36 | } 37 | a[i][y] =- a[i][y] * a[x][y]; 38 | } 39 | } 40 | z += c[y] * b[x]; 41 | for (int i = 0; i < m; i++) { 42 | if (i != y) c[i] -= c[y] * a[x][i]; 43 | } 44 | c[y] =- c[y] * a[x][y]; 45 | } 46 | 47 | pair> maximize() { 48 | while (true) { 49 | int x = -1, y = -1; 50 | lf mn = -EPS; 51 | for (int i = 0; i < n; i++) { 52 | if (b[i] < mn) mn = b[i], x = i; 53 | } 54 | if (x < 0) break; 55 | for (int i = 0; i < m; i++) { 56 | if (a[x][i] < -EPS) { 57 | y = i; 58 | break; 59 | } 60 | } 61 | assert(y >= 0); // no hay solución para Ax <= b 62 | pivot(x, y); 63 | } 64 | while (true) { 65 | lf mx = EPS; 66 | int x = -1, y = -1; 67 | for (int i = 0; i < m; i++) { 68 | if (c[i] > mx) mx = c[i], y = i; 69 | } 70 | if (y < 0) break; 71 | lf mn = 1e200; 72 | for (int i = 0; i < n; i++) { 73 | if (a[i][y] > EPS && b[i] / a[i][y] < mn) 74 | mn = b[i] / a[i][y], x = i; 75 | } 76 | assert(x >= 0); // unbounded 77 | pivot(x, y); 78 | } 79 | vector r(m); 80 | for (int i = 0; i < n; i++) { 81 | if (Y[i] < m) r[Y[i]] = b[i]; 82 | } 83 | return {z, r}; 84 | } 85 | }; 86 | -------------------------------------------------------------------------------- /c++/Graphs/Articulation Bridges Biconnected.cpp: -------------------------------------------------------------------------------- 1 | Dado un grafo no dirigido halla los puntos de articulación, puentes y componentes biconexas. Para construir el block cut tree quitar los comentarios. 2 | 3 | struct edge { 4 | int u, v, comp; // A que componente biconexa pertenece 5 | bool bridge; // Si la arista es un puente 6 | }; 7 | 8 | const int MX = 1e5+5; // Cantidad maxima de nodos 9 | vector g[MX]; // Lista de adyacencia 10 | vector e; // Lista de aristas 11 | stack st; 12 | int low[MX], num[MX], cont; 13 | bool art[MX]; // Si el nodo es un punto de articulacion 14 | // vector> comps; // Componentes biconexas 15 | // vector> tree; // Block cut tree 16 | // vector id; // Id del nodo en el block cut tree 17 | int BCC; // Cantidad de componentes biconexas 18 | int n, m; // Cantidad de nodos y aristas 19 | 20 | void add_edge(int u, int v) { 21 | g[u].pb(e.size()); 22 | g[v].pb(e.size()); 23 | e.pb({u, v, -1, false}); 24 | } 25 | 26 | void dfs(int u, int p = -1) { 27 | low[u] = num[u] = cont++; 28 | for (auto &i : g[u]) { 29 | edge &ed = e[i]; 30 | int v = ed.u^ed.v^u; 31 | if (num[v] == -1) { 32 | st.push(i); 33 | dfs(v, i); 34 | if (low[v] > num[u]) 35 | ed.bridge = true; // bridge 36 | if (low[v] >= num[u]) { 37 | art[u] = (num[u] > 0 || num[v] > 1); // articulation 38 | int last; // start biconnected 39 | // comps.pb({}); 40 | do { 41 | last = st.top(); st.pop(); 42 | e[last].comp = BCC; 43 | // comps.back().insert(e[last].u); 44 | // comps.back().insert(e[last].v); 45 | } while (last != i); 46 | BCC++; // end biconnected 47 | } 48 | low[u] = min(low[u], low[v]); 49 | } else if (i != p && num[v] < num[u]) { 50 | st.push(i); 51 | low[u] = min(low[u], num[v]); 52 | } 53 | } 54 | } 55 | 56 | void build_tree() { 57 | tree.clear(); id.resize(n); 58 | for (int u = 0; u < n; u++) { 59 | if (art[u]) { 60 | id[u] = tree.size(); 61 | tree.pb({}); 62 | } 63 | } 64 | for (auto &comp : comps) { 65 | int node = tree.size(); 66 | tree.pb({}); 67 | for (auto &u : comp) { 68 | if (art[u]) { 69 | tree[id[u]].pb(node); 70 | tree[node].pb(id[u]); 71 | } else id[u] = node; 72 | } 73 | } 74 | } 75 | 76 | void init() { 77 | cont = BCC = 0; 78 | // comps.clear(); 79 | e.clear(); 80 | for (int i = 0; i <= n; i++) { 81 | g[i].clear(); 82 | num[i] = -1; // no visitado 83 | art[i] = false; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /c++/Geometry/Point.cpp: -------------------------------------------------------------------------------- 1 | typedef double lf; 2 | const lf eps = 1e-9; 3 | const lf PI = acos(-1.0); 4 | typedef double T; 5 | struct pt { 6 | T x, y; 7 | pt operator + (pt p) { return {x+p.x, y+p.y}; } 8 | pt operator - (pt p) { return {x-p.x, y-p.y}; } 9 | pt operator * (pt p) { return {x*p.x-y*p.y, x*p.y+y*p.x}; } 10 | pt operator * (T d) { return {x*d, y*d}; } 11 | pt operator / (lf d) { return {x/d, y/d}; } // only for floating point 12 | bool operator == (pt b) { return x == b.x && y == b.y; } 13 | bool operator != (pt b) { return !(*this == b); } 14 | bool operator < (const pt &o) const { return y < o.y || (y == o.y && x < o.x); } 15 | bool operator > (const pt &o) const { return y > o.y || (y == o.y && x > o.x); } 16 | }; 17 | int cmp(lf a, lf b) { return (a + eps < b ? -1 :(b + eps < a ? 1 : 0)); } // double comparator 18 | 19 | T norm(pt a) { return a.x*a.x + a.y*a.y; } 20 | lf abs(pt a) { return sqrt(norm(a)); } 21 | lf arg(pt a) { return atan2(a.y, a.x); } 22 | pt unit(pt a) { return a/abs(a); } 23 | 24 | T dot(pt a, pt b) { return a.x*b.x + a.y*b.y; } // x = 90 -> cos = 0 25 | T cross(pt a, pt b) { return a.x*b.y - a.y*b.x; } // x = 180 -> sin = 0 26 | T orient(pt a, pt b, pt c) { return cross(b-a, c-a); } // clockwise = - 27 | pt rot(pt p, lf a) { return {p.x*cos(a) - p.y*sin(a), p.x*sin(a) + p.y*cos(a)}; } 28 | pt rotate_to_b(pt a, pt b, lf ang) { return rot(a-b, ang)+b; } // rotate by ang center b 29 | pt rot90ccw(pt p) { return {-p.y, p.x}; } 30 | pt rot90cw(pt p) { return {p.y, -p.x}; } 31 | pt translate(pt p, pt v) { return p+v; } 32 | pt scale(pt p, double f, pt c) { return c + (p-c)*f; } // c-center 33 | bool are_perp(pt v, pt w) { return dot(v, w) == 0; } 34 | int sign(T x) { return (T(0) < x) - (x < T(0)); } 35 | 36 | bool in_angle(pt a, pt b, pt c, pt x) { // x inside angle abc (center in a) 37 | assert(orient(a, b, c) != 0); 38 | if (orient(a, b, c) < 0) swap(b, c); 39 | return orient(a, b, x) >= 0 && orient(a, c, x) <= 0; 40 | } 41 | // angle bwn 2 vectors [0, pi] -> [0, 180] and (-pi, 0) -> (180, 360) 42 | lf angle(pt a, pt b) { return acos(max(-1.0, min(1.0, dot(a, b)/abs(a)/abs(b)))); } 43 | lf angle(pt a, pt b) { return atan2(cross(a, b), dot(a, b)); } 44 | lf angle360(pt a, pt b) { // [0, 360) 45 | lf ang = angle(a, b); return (ang < 0 ? ang+2*PI : ang) * 360/(2*PI); 46 | } 47 | // returns vector to transform points 48 | pt get_linear_transformation(pt p, pt q, pt r, pt fp, pt fq) { 49 | pt pq = q-p, num{cross(pq, fq-fp), dot(pq, fq-fp)}; 50 | return fp + pt{cross(r-p, num), dot(r-p, num)} / norm(pq); 51 | } 52 | bool half(pt p) { // true if is in (0, 180] (line is x axis) 53 | assert(p.x != 0 || p.y != 0); // the argument of (0, 0) is undefined 54 | return p.y > 0 || (p.y == 0 && p.x < 0); 55 | } 56 | bool half_from(pt p, pt v = {1, 0}) { // line is v (above v is true) 57 | return cross(v, p) < 0 || (cross(v, p) == 0 && dot(v, p) < 0); 58 | } 59 | bool polar_cmp(const pt &a, const pt &b) { // polar sort 60 | return make_tuple(half(a), 0) < make_tuple(half(b), cross(a, b)); 61 | // return make_tuple(half(a), 0, sq(a)) < make_tuple(half(b), cross(a, b), sq(b)); // further ones appear later 62 | } 63 | -------------------------------------------------------------------------------- /c++/Network flows/Blossom.cpp: -------------------------------------------------------------------------------- 1 | Halla el máximo match en un grafo general O(E * v ^2) 2 | 3 | struct network { 4 | struct struct_edge { 5 | int v; struct_edge * n; 6 | }; 7 | typedef struct_edge* edge; 8 | 9 | int n; 10 | struct_edge pool[MAXE]; // 2*n*n; 11 | edge top; 12 | vector adj; 13 | queue q; 14 | vector f, base, inq, inb, inp, match; 15 | vector> ed; 16 | 17 | network(int n) : n(n), match(n, -1), adj(n), top(pool), f(n), base(n), 18 | inq(n), inb(n), inp(n), ed(n, vector(n)) {} 19 | 20 | void add_edge(int u, int v) { 21 | if (ed[u][v]) return; 22 | ed[u][v] = 1; 23 | top->v = v, top->n = adj[u], adj[u] = top++; 24 | top->v = u, top->n = adj[v], adj[v] = top++; 25 | } 26 | 27 | int get_lca(int root, int u, int v) { 28 | fill(inp.begin(), inp.end(), 0); 29 | while (1) { 30 | inp[u = base[u]] = 1; 31 | if (u == root) break; 32 | u = f[match[u]]; 33 | } 34 | while (1) { 35 | if (inp[v = base[v]]) return v; 36 | else v = f[match[v]]; 37 | } 38 | } 39 | 40 | void mark(int lca, int u) { 41 | while (base[u] != lca) { 42 | int v = match[u]; 43 | inb[base[u]] = 1; 44 | inb[base[v]] = 1; 45 | u = f[v]; 46 | if (base[u] != lca) f[u] = v; 47 | } 48 | } 49 | 50 | void blossom_contraction(int s, int u, int v) { 51 | int lca = get_lca(s, u, v); 52 | fill(inb.begin(), inb.end(), 0); 53 | mark(lca, u); mark(lca, v); 54 | if (base[u] != lca) f[u] = v; 55 | if (base[v] != lca) f[v] = u; 56 | for (int u = 0; u < n; u++) { 57 | if (inb[base[u]]) { 58 | base[u] = lca; 59 | if (!inq[u]) { 60 | inq[u] = 1; 61 | q.push(u); 62 | } 63 | } 64 | } 65 | } 66 | 67 | int bfs(int s) { 68 | fill(inq.begin(), inq.end(), 0); 69 | fill(f.begin(), f.end(), -1); 70 | for (int i = 0; i < n; i++) base[i] = i; 71 | q = queue(); 72 | q.push(s); 73 | inq[s] = 1; 74 | while (q.size()) { 75 | int u = q.front(); q.pop(); 76 | for (edge e = adj[u]; e; e = e->n) { 77 | int v = e->v; 78 | if (base[u] != base[v] && match[u] != v) { 79 | if ((v == s) || (match[v] != -1 && f[match[v]] != -1)) { 80 | blossom_contraction(s, u, v); 81 | } else if (f[v] == -1) { 82 | f[v] = u; 83 | if (match[v] == -1) return v; 84 | else if (!inq[match[v]]) { 85 | inq[match[v]] = 1; 86 | q.push(match[v]); 87 | } 88 | } 89 | } 90 | } 91 | } 92 | return -1; 93 | } 94 | 95 | int doit(int u) { 96 | if (u == -1) return 0; 97 | int v = f[u]; 98 | doit(match[v]); 99 | match[v] = u; match[u] = v; 100 | return u != -1; 101 | } 102 | 103 | // (i < net.match[i]) => means match 104 | int maximum_matching() { 105 | int ans = 0; 106 | for (int u = 0; u < n; u++) 107 | ans += (match[u] == -1) && doit(bfs(u)); 108 | return ans; 109 | } 110 | }; 111 | -------------------------------------------------------------------------------- /c++/Network flows/MinCost MaxFlow.cpp: -------------------------------------------------------------------------------- 1 | Dado un grafo, halla el flujo maximo y el costo minimo entre el source s y el sink t. 2 | 3 | struct edge { 4 | int u, v, cap, flow, cost; 5 | int rem() { return cap - flow; } 6 | }; 7 | 8 | const int inf = 1e9; 9 | const int MX = 405; // Cantidad maxima TOTAL de nodos 10 | vector g[MX]; // Lista de adyacencia 11 | vector e; // Lista de aristas 12 | vector in_queue; // Marca los nodos que estan en cola 13 | vector pre, dist, cap; // Almacena el nodo anterior, la distancia y el flujo de cada nodo 14 | int mxflow, mncost; // Flujo maximo y costo minimo 15 | int N; // Cantidad TOTAL de nodos 16 | 17 | void add_edge(int u, int v, int cap, int cost) { 18 | g[u].pb(e.size()); 19 | e.pb({u, v, cap, 0, cost}); 20 | g[v].pb(e.size()); 21 | e.pb({v, u, 0, 0, -cost}); 22 | } 23 | 24 | void flow(int s, int t) { 25 | mxflow = mncost = 0; 26 | in_queue.assign(N, false); 27 | while (true) { 28 | dist.assign(N, inf); dist[s] = 0; 29 | cap.assign(N, 0); cap[s] = inf; 30 | pre.assign(N, -1); pre[s] = 0; 31 | queue q; q.push(s); 32 | in_queue[s] = true; 33 | 34 | while (q.size()) { 35 | int u = q.front(); q.pop(); 36 | in_queue[u] = false; 37 | for (int &id : g[u]) { 38 | edge &ed = e[id]; 39 | int v = ed.v; 40 | if (ed.rem() && dist[v] > dist[u]+ed.cost) { 41 | dist[v] = dist[u]+ed.cost; 42 | cap[v] = min(cap[u], ed.rem()); 43 | pre[v] = id; 44 | if (!in_queue[v]) { 45 | q.push(v); 46 | in_queue[v] = true; 47 | } 48 | } 49 | } 50 | } 51 | if (pre[t] == -1) break; 52 | mxflow += cap[t]; 53 | mncost += cap[t] * dist[t]; 54 | for (int v = t; v != s; v = e[pre[v]].u) { 55 | e[pre[v]].flow += cap[t]; 56 | e[pre[v]^1].flow -= cap[t]; 57 | } 58 | } 59 | } 60 | 61 | void init() { 62 | e.clear(); 63 | for (int i = 0; i <= N; i++) { 64 | g[i].clear(); 65 | } 66 | } 67 | 68 | // O(V * E * 2 * log(E)) 69 | template 70 | struct mcmf { 71 | struct edge { int u, v, cap, flow; type cost; }; 72 | 73 | int n; 74 | vector ed; 75 | vector> g; 76 | vector p; 77 | vector d, phi; 78 | 79 | mcmf(int n) : n(n), g(n), p(n), d(n), phi(n) {} 80 | 81 | void add_edge(int u, int v, int cap, type cost) { 82 | g[u].pb(ed.size()); 83 | ed.pb({u, v, cap, 0, cost}); 84 | g[v].pb(ed.size()); 85 | ed.pb({v, u, 0, 0, -cost}); 86 | } 87 | 88 | bool dijkstra(int s, int t) { 89 | fill(d.begin(), d.end(), INF); 90 | fill(p.begin(), p.end(), -1); 91 | set> q; 92 | d[s] = 0; 93 | for (q.insert({d[s], s}); q.size();) { 94 | int u = (*q.begin()).second; q.erase(q.begin()); 95 | for (auto v : g[u]) { 96 | auto &e = ed[v]; 97 | type nd = d[e.u]+e.cost+phi[e.u]-phi[e.v]; 98 | if (0 < (e.cap-e.flow) && nd < d[e.v]) { 99 | q.erase({d[e.v], e.v}); 100 | d[e.v] = nd; p[e.v] = v; 101 | q.insert({d[e.v], e.v}); 102 | } 103 | } 104 | } 105 | for (int i = 0; i < n; i++) phi[i] = min(INF, phi[i]+d[i]); 106 | return d[t] != INF; 107 | } 108 | 109 | pair max_flow(int s, int t) { 110 | type mc = 0; 111 | int mf = 0; 112 | fill(phi.begin(), phi.end(), 0); 113 | while (dijkstra(s, t)) { 114 | int flow = INF; 115 | for (int v = p[t]; v != -1; v = p[ed[v].u]) 116 | flow = min(flow, ed[v].cap-ed[v].flow); 117 | for (int v = p[t]; v != -1; v = p[ed[v].u]) { 118 | edge &e1 = ed[v]; 119 | edge &e2 = ed[v^1]; 120 | mc += e1.cost*flow; 121 | e1.flow += flow; 122 | e2.flow -= flow; 123 | } 124 | mf += flow; 125 | } 126 | return {mf, mc}; 127 | } 128 | }; 129 | -------------------------------------------------------------------------------- /c++/Values sequences and results/Sequences.tex: -------------------------------------------------------------------------------- 1 | Listado de secuencias mas comunes y como hallarlas. 2 | 3 | \begin{center} 4 | \tablefirsthead{} 5 | \tabletail{ 6 | \midrule 7 | \multicolumn{2}{r}{{Continúa en la siguiente columna}} \\} 8 | \tablelasttail{} 9 | {\renewcommand{\arraystretch}{1.4} 10 | \begin{supertabular}{|p{1.8cm}|p{8.6cm}|} 11 | 12 | \hline 13 | 14 | \multirow{2}{2cm}{Estrellas octangulares} 15 | & 0, 1, 14, 51, 124, 245, 426, 679, 1016, 1449, 1990, 2651, ... 16 | \\ \cline{2-2} 17 | & $f(n) = n*(2*n^{2} - 1)$. 18 | \\ \hline 19 | 20 | \multirow{2}{2cm} 21 | {Euler totient} 22 | & 1, 1, 2, 2, 4, 2, 6, 4, 6, 4, 10, 4, 12, 6,... 23 | \\ \cline{2-2} 24 | & $f(n) = $ Cantidad de números naturales $\leq n$ coprimos con n. 25 | \\ \hline 26 | 27 | \multirow{2}{2cm}{Números de Bell} 28 | & 1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, 115975, ... 29 | \\ \cline{2-2} 30 | & Se inicia una matriz triangular con f[0][0] = f[1][0] = 1. La suma de estos dos se guarda en f[1][1] y se traslada a f[2][0]. Ahora se suman f[1][0] con f[2][0] y se guarda en f[2][1]. Luego se suman f[1][1] con f[2][1] y se guarda en f[2][2] trasladandose a f[3][0] y así sucesivamente. Los valores de la primera columna contienen la respuesta. 31 | \\ \hline 32 | 33 | \multirow{2}{2cm} 34 | {Números de Catalán} 35 | & 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, ... 36 | \\ \cline{2-2} 37 | & $f(n)=\displaystyle\frac{(2n)!}{(n + 1)! n!}$ 38 | 39 | \\ \hline 40 | 41 | \multirow{2}{2cm}{Números de Fermat} 42 | & 3, 5, 17, 257, 65537, 4294967297, 18446744073709551617, ... 43 | \\ \cline{2-2} 44 | & $f(n) = 2^{(\displaystyle2^{\textstyle n})} + 1$ 45 | \\ \hline 46 | 47 | \multirow{2}{2cm} 48 | {Números de Fibonacci} 49 | & 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, ... 50 | \\ \cline{2-2} 51 | & $f(0) = 0$; $f(1) = 1$; $f(n) = f(n-1) + f(n-2)$ para $n>1$ \\ \hline 52 | 53 | \multirow{2}{2cm} 54 | {Números de Lucas} 55 | & 2, 1, 3, 4, 7, 11, 18, 29, 47, 76, 123, 199, 322, ... 56 | \\ \cline{2-2} 57 | & $f(0) = 2$; $f(1) = 1$; $f(n) = f(n-1) + f(n-2)$ para $n>1$ 58 | \\ \hline 59 | 60 | \multirow{2}{2cm}{Números de Pell} 61 | & 0, 1, 2, 5, 12, 29, 70, 169, 408, 985, 2378, 5741, 13860, ... 62 | \\ \cline{2-2} 63 | & $f(0) = 0; f(1) = 1; f(n) = 2f(n-1) + f(n-2)$ para $n>1$ 64 | \\ \hline 65 | 66 | \multirow{2}{2cm} 67 | {Números de Tribonacci} 68 | & 0, 0, 1, 1, 2, 4, 7, 13, 24, 44, 81, 149, 274, 504, ... 69 | \\ \cline{2-2} 70 | & $f(0)=f(1)=0; f(2)=1; f(n) = f(n-1) + f(n-2) + f(n-3)$ para $n>2$ 71 | \\ \hline 72 | 73 | \multirow{2}{2cm}{Números factoriales} 74 | & 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, ... 75 | \\ \cline{2-2} 76 | &$ f(0) = 1; f(n) = \displaystyle\prod_{\textstyle k=1}^{\textstyle n}k$ para $n>0$. 77 | 78 | \\ \hline 79 | 80 | \multirow{2}{2cm}{Números piramidales cuadrados} 81 | & 0, 1, 5, 14, 30, 55, 91, 140, 204, 285, 385, 506, 650, ... 82 | \\ \cline{2-2} 83 | & $f(n) = \displaystyle\frac{n*(n+1)*(2*n+1)}{6}$ 84 | 85 | \\ \hline 86 | 87 | \multirow{2}{2cm}{Números primos de Mersenne} 88 | & 3, 7, 31, 127, 8191, 131071, 524287, 2147483647, ... 89 | \\ \cline{2-2} 90 | & $f(n) = 2^{p(n)} - 1$ donde $p$ representa valores primos iniciando en $p(0)=2$. 91 | \\ \hline 92 | 93 | 94 | \multirow{2}{2cm}{Números tetraedrales} 95 | & 1, 4, 10, 20, 35, 56, 84, 120, 165, 220, 286, 364, 455, ... 96 | \\ \cline{2-2} 97 | & $f(n) = \displaystyle\frac{n*(n+1)*(n+2)}{6}$ 98 | 99 | \\ \hline 100 | 101 | \multirow{2}{2cm}{Números triangulares} 102 | & 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, ... 103 | \\ \cline{2-2} 104 | & $f(n) = \displaystyle\frac{n(n+1)}{2}$ 105 | 106 | \\ \hline 107 | 108 | \multirow{2}{2cm}{OEIS A000127} 109 | & 1, 2, 4, 8, 16, 31, 57, 99, 163, 256, 386, 562, ... 110 | \\ \cline{2-2} 111 | & $f(n) = \displaystyle\frac{(n^{4}-6n^{3}+23n^{2}-18{n}+24)}{24}$. 112 | 113 | \\ \hline 114 | 115 | \multirow{2}{2cm}{Secuencia de Narayana} 116 | & 1, 1, 1, 2, 3, 4, 6, 9, 13, 19, 28, 41, 60, 88, 129, ... 117 | \\ \cline{2-2} 118 | & $f(0) = f(1) = f(2) = 1; f(n) = f(n-1) + f(n-3)$ para todo $n>2$. 119 | \\ \hline 120 | 121 | \multirow{2}{2cm} 122 | {Secuencia de Silvestre} 123 | & 2, 3, 7, 43, 1807, 3263443, 10650056950807, ... 124 | \\ \cline{2-2} 125 | & $f(0) = 2; f(n+1) = f(n)^2 - f(n) + 1$ 126 | \\ \hline 127 | 128 | \multirow{2}{2cm}{Secuencia de vendedor perezoso} 129 | & 1, 2, 4, 7, 11, 16, 22, 29, 37, 46, 56, 67, 79, 92, 106, ... 130 | \\ \cline{2-2} 131 | & Equivale al triangular(n) + 1. Máxima número de piezas que se pueden formar al hacer n cortes a un disco. 132 | 133 | $f(n) = \displaystyle\frac{n(n+1)}{2} + 1$ 134 | 135 | \\ \hline 136 | 137 | \multirow{2}{2cm}{Suma de los divisores de un número} 138 | & 1, 3, 4, 7, 6, 12, 8, 15, 13, 18, 12, 28, 14, 24, ... 139 | \\ \cline{2-2} 140 | &Para todo $n>1$ cuya descomposición en factores primos es $n=\displaystyle p_{1}^{\textstyle a_{1}}\displaystyle p_{2}^{\textstyle a_{2}}...\displaystyle p_{k}^{\textstyle a_{k}}$ se tiene que: 141 | 142 | $f(n) = \displaystyle\frac{p_{1}^{a_{1} + 1} - 1}{p_{1} - 1} * \frac{p_{2}^{a_{2} + 1} - 1}{p_{2} - 1} * ... * \frac{p_{k}^{a_{k} + 1} - 1}{p_{k} - 1}$ 143 | 144 | \\ \hline 145 | \end{supertabular} 146 | } 147 | \end{center} 148 | -------------------------------------------------------------------------------- /java [outdated]/Values sequences and results/Sequences.tex: -------------------------------------------------------------------------------- 1 | Listado de secuencias mas comunes y como hallarlas. 2 | 3 | \begin{center} 4 | \tablefirsthead{} 5 | \tabletail{ 6 | \midrule 7 | \multicolumn{2}{r}{{Continúa en la siguiente columna}} \\} 8 | \tablelasttail{} 9 | {\renewcommand{\arraystretch}{1.4} 10 | \begin{supertabular}{|p{1.8cm}|p{8.6cm}|} 11 | 12 | \hline 13 | 14 | \multirow{2}{2cm}{Estrellas octangulares} 15 | & 0, 1, 14, 51, 124, 245, 426, 679, 1016, 1449, 1990, 2651, ... 16 | \\ \cline{2-2} 17 | & $f(n) = n*(2*n^{2} - 1)$. 18 | \\ \hline 19 | 20 | 21 | \multirow{2}{2cm} 22 | {Euler totient} 23 | & 1, 1, 2, 2, 4, 2, 6, 4, 6, 4, 10, 4, 12, 6,... 24 | \\ \cline{2-2} 25 | & $f(n) = $ Cantidad de números naturales $\leq n$ coprimos con n. 26 | \\ \hline 27 | 28 | \multirow{2}{2cm}{Números de Bell} 29 | & 1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, 115975, ... 30 | \\ \cline{2-2} 31 | & Se inicia una matriz triangular con f[0][0] = f[1][0] = 1. La suma de estos dos se guarda en f[1][1] y se traslada a f[2][0]. Ahora se suman f[1][0] con f[2][0] y se guarda en f[2][1]. Luego se suman f[1][1] con f[2][1] y se guarda en f[2][2] trasladandose a f[3][0] y así sucesivamente. Los valores de la primera columna contienen la respuesta. 32 | \\ \hline 33 | 34 | 35 | \multirow{2}{2cm} 36 | {Números de Catalán} 37 | & 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, ... 38 | \\ \cline{2-2} 39 | & $f(n)=\displaystyle\frac{(2n)!}{(n + 1)! n!}$ 40 | 41 | \\ \hline 42 | 43 | \multirow{2}{2cm}{Números de Fermat} 44 | & 3, 5, 17, 257, 65537, 4294967297, 18446744073709551617, ... 45 | \\ \cline{2-2} 46 | & $f(n) = 2^{(\displaystyle2^{\textstyle n})} + 1$ 47 | \\ \hline 48 | 49 | 50 | \multirow{2}{2cm} 51 | {Números de Fibonacci} 52 | & 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, ... 53 | \\ \cline{2-2} 54 | & $f(0) = 0$; $f(1) = 1$; $f(n) = f(n-1) + f(n-2)$ para $n>1$ \\ \hline 55 | 56 | \multirow{2}{2cm} 57 | {Números de Lucas} 58 | & 2, 1, 3, 4, 7, 11, 18, 29, 47, 76, 123, 199, 322, ... 59 | \\ \cline{2-2} 60 | & $f(0) = 2$; $f(1) = 1$; $f(n) = f(n-1) + f(n-2)$ para $n>1$ 61 | \\ \hline 62 | 63 | \multirow{2}{2cm}{Números de Pell} 64 | & 0, 1, 2, 5, 12, 29, 70, 169, 408, 985, 2378, 5741, 13860, ... 65 | \\ \cline{2-2} 66 | & $f(0) = 0; f(1) = 1; f(n) = 2f(n-1) + f(n-2)$ para $n>1$ 67 | \\ \hline 68 | 69 | \multirow{2}{2cm} 70 | {Números de Tribonacci} 71 | & 0, 0, 1, 1, 2, 4, 7, 13, 24, 44, 81, 149, 274, 504, ... 72 | \\ \cline{2-2} 73 | & $f(0)=f(1)=0; f(2)=1; f(n) = f(n-1) + f(n-2) + f(n-3)$ para $n>2$ 74 | \\ \hline 75 | 76 | \multirow{2}{2cm}{Números factoriales} 77 | & 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, ... 78 | \\ \cline{2-2} 79 | &$ f(0) = 1; f(n) = \displaystyle\prod_{\textstyle k=1}^{\textstyle n}k$ para $n>0$. 80 | 81 | \\ \hline 82 | 83 | \multirow{2}{2cm}{Números piramidales cuadrados} 84 | & 0, 1, 5, 14, 30, 55, 91, 140, 204, 285, 385, 506, 650, ... 85 | \\ \cline{2-2} 86 | & $f(n) = \displaystyle\frac{n*(n+1)*(2*n+1)}{6}$ 87 | 88 | \\ \hline 89 | 90 | \multirow{2}{2cm}{Números primos de Mersenne} 91 | & 3, 7, 31, 127, 8191, 131071, 524287, 2147483647, ... 92 | \\ \cline{2-2} 93 | & $f(n) = 2^{p(n)} - 1$ donde $p$ representa valores primos iniciando en $p(0)=2$. 94 | \\ \hline 95 | 96 | 97 | \multirow{2}{2cm}{Números tetraedrales} 98 | & 1, 4, 10, 20, 35, 56, 84, 120, 165, 220, 286, 364, 455, ... 99 | \\ \cline{2-2} 100 | & $f(n) = \displaystyle\frac{n*(n+1)*(n+2)}{6}$ 101 | 102 | \\ \hline 103 | 104 | 105 | \multirow{2}{2cm}{Números triangulares} 106 | & 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, ... 107 | \\ \cline{2-2} 108 | & $f(n) = \displaystyle\frac{n(n+1)}{2}$ 109 | 110 | \\ \hline 111 | 112 | 113 | \multirow{2}{2cm}{OEIS A000127} 114 | & 1, 2, 4, 8, 16, 31, 57, 99, 163, 256, 386, 562, ... 115 | \\ \cline{2-2} 116 | & $f(n) = \displaystyle\frac{(n^{4}-6n^{3}+23n^{2}-18{n}+24)}{24}$. 117 | 118 | \\ \hline 119 | 120 | 121 | \multirow{2}{2cm}{Secuencia de Narayana} 122 | & 1, 1, 1, 2, 3, 4, 6, 9, 13, 19, 28, 41, 60, 88, 129, ... 123 | \\ \cline{2-2} 124 | & $f(0) = f(1) = f(2) = 1; f(n) = f(n-1) + f(n-3)$ para todo $n>2$. 125 | \\ \hline 126 | 127 | 128 | \multirow{2}{2cm} 129 | {Secuencia de Silvestre} 130 | & 2, 3, 7, 43, 1807, 3263443, 10650056950807, ... 131 | \\ \cline{2-2} 132 | & $f(0) = 2; f(n+1) = f(n)^2 - f(n) + 1$ 133 | \\ \hline 134 | 135 | \multirow{2}{2cm}{Secuencia de vendedor perezoso} 136 | & 1, 2, 4, 7, 11, 16, 22, 29, 37, 46, 56, 67, 79, 92, 106, ... 137 | \\ \cline{2-2} 138 | & Equivale al triangular(n) + 1. Máxima número de piezas que se pueden formar al hacer n cortes a un disco. 139 | 140 | $f(n) = \displaystyle\frac{n(n+1)}{2} + 1$ 141 | 142 | \\ \hline 143 | 144 | \multirow{2}{2cm}{Suma de los divisores de un número} 145 | & 1, 3, 4, 7, 6, 12, 8, 15, 13, 18, 12, 28, 14, 24, ... 146 | \\ \cline{2-2} 147 | &Para todo $n>1$ cuya descomposición en factores primos es $n=\displaystyle p_{1}^{\textstyle a_{1}}\displaystyle p_{2}^{\textstyle a_{2}}...\displaystyle p_{k}^{\textstyle a_{k}}$ se tiene que: 148 | 149 | 150 | $f(n) = \displaystyle\frac{p_{1}^{a_{1} + 1} - 1}{p_{1} - 1} * \frac{p_{2}^{a_{2} + 1} - 1}{p_{2} - 1} * ... * \frac{p_{k}^{a_{k} + 1} - 1}{p_{k} - 1}$ 151 | 152 | \\ \hline 153 | \end{supertabular} 154 | } 155 | \end{center} 156 | --------------------------------------------------------------------------------