1. Ad-hoc
1.1. Invertir Bytes
1.2. Ao bisiesto .
1.3. Doomsday . .
1.4. Hanoi . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3
3
3
3
3
2. Estructuras
2.1. Union - Find . . . . . . . . . . . . .
2.2. BIT . . . . . . . . . . . . . . . . .
2.3. Segment Tree . . . . . . . . . . . .
2.4. Segment Tree con Lazy Propagatin
2.5. Trie . . . . . . . . . . . . . . . . .
2.6. Arbol Binario de Busqueda . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4
4
5
5
7
8
10
3. Complete Search
3.1. El problema de las ocho reinas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2. El problema de las ocho reinas acelerado con Bits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
12
13
4. Divide y venceras
4.1. Busqueda Binaria (Recursivo)
4.2. Busqueda Binaria (Iterativo) .
4.3. MergeSort . . . . . . . . . . .
4.4. Meet in the Middle . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
14
14
14
15
16
5. Programacin Dinamica
5.1. El problema de la mochila y Subset Sum . . . . .
5.2. El problema de la mochila(iterativo) . . . . . . .
5.3. Cambio de modenas . . . . . . . . . . . . . . . .
5.4. LIS (O(n2 )) . . . . . . . . . . . . . . . . . . . .
5.5. LIS (O(n log(n)) . . . . . . . . . . . . . . . . .
5.6. Suma maxima en rango . . . . . . . . . . . . . .
5.7. Suma maxima en rango 2D O(n4 ) . . . . . . . .
5.8. Suma maxima en rango 2D O(n3 ) . . . . . . . .
5.9. Maxima submatriz de ceros . . . . . . . . . . . .
5.10. Submatriz de suma maxima . . . . . . . . . . . .
5.11. Distancia de edicin (Algoritmo de Levenshtein)
5.12. Distancia de edicin (Recursivo) . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
18
18
19
20
21
21
22
22
23
23
24
25
26
6. Grafos
6.1. BFS . . . . . . . . . . . . . . . . . . . . . . .
6.2. DFS . . . . . . . . . . . . . . . . . . . . . . .
6.3. Topological Sort . . . . . . . . . . . . . . . . .
6.4. Dijkstra . . . . . . . . . . . . . . . . . . . . .
6.5. BellmandFord . . . . . . . . . . . . . . . . . .
6.6. Floyd Warshall . . . . . . . . . . . . . . . . .
6.7. Componentes Fuertemente Conexas . . . . . .
6.8. Componentes Fuertemente Conexas (Kosaraju)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
27
27
27
28
28
29
30
31
32
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
NDICE GENERAL
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
33
35
36
38
39
40
41
43
44
45
46
7. Matemticas
7.1. GCD . . . . . . . . . . . . . . . . . . . . . . .
7.2. LCM . . . . . . . . . . . . . . . . . . . . . . .
7.3. Algoritmo extendido de euclides . . . . . . . .
7.4. Exponenciacin rapida . . . . . . . . . . . . .
7.5. Criba de Erathostenes . . . . . . . . . . . . . .
7.6. Criba de Erathostenes Aumentada . . . . . . .
7.7. Triangulo de Pascal . . . . . . . . . . . . . . .
7.8. Combinaciones(Para numeros muy grandes) . .
7.9. Polinomios . . . . . . . . . . . . . . . . . . .
7.10. Fibonacci ( O(log(n)) ) . . . . . . . . . . . . .
7.11. Multiplicacin entero por cadena . . . . . . . .
7.12. Multiplicacin de numeros grandes (Karatsuba)
7.13. Integracion de Simpson . . . . . . . . . . . . .
7.14. Inverso modular . . . . . . . . . . . . . . . . .
7.15. El juego de Nim . . . . . . . . . . . . . . . . .
7.16. Fraccion . . . . . . . . . . . . . . . . . . . . .
7.17. Matriz . . . . . . . . . . . . . . . . . . . . . .
7.18. Gauss Jordan . . . . . . . . . . . . . . . . . .
7.19. Numeros romanos . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
47
47
47
47
48
48
49
49
49
50
51
51
52
52
53
53
53
55
56
59
8. Cadenas
8.1. Utilidades . . . . . . . . . . . . . . .
8.2. Boyer Moore . . . . . . . . . . . . .
8.3. Knuth Morris Pratt . . . . . . . . . .
8.4. Iesima permutacin . . . . . . . . . .
8.5. Algoritmo de Manacher . . . . . . . .
8.6. Longest Common Subsequence (LCS)
8.7. Suffix Array . . . . . . . . . . . . . .
8.8. Suffix Array DC3 . . . . . . . . . . .
8.9. Minima Rotacion Lexicografica . . .
8.10. Trie . . . . . . . . . . . . . . . . . .
8.11. Aplicaciones . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
60
60
60
61
62
62
64
64
67
68
69
71
9. Geometria Computacional
9.1. Interseccin de rectangulos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.2. Distancia Punto - Segmento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.3. Distancia Punto - Recta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
73
73
73
74
10. Utilitarios
10.1. Plantilla . . . . . . . . . . . . . . . . . . . .
10.2. Lectura rapida . . . . . . . . . . . . . . . . .
10.3. Espicificadores de formato para printf y scanf
10.4. Contar bits en 1 en un numero . . . . . . . .
10.5. Busqueda binaria . . . . . . . . . . . . . . .
75
75
76
76
76
77
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Captulo 1
Ad-hoc
1.1.
1
2
3
4
5
6
7
8
1.2.
1
2
3
Doomsday
//Entrada: Una fecha (ene = 1, ..., dic = 12) Salida: Dia de la semana
string vec[7] = {"DOM","LUN","MAR","MIE","JUE","VIE","SAB"};
string doomsday(int dia, int mes, int anio){
int a, y, m, d;
a = (14 - mes) / 12;
y = anio - a;
m = mes + 12 * a - 2;
d = (dia + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
return vec[d];
}
1.4.
1
2
3
4
Ao bisiesto
1.3.
1
2
3
4
5
6
7
8
9
10
Invertir Bytes
Hanoi
Captulo 2
Estructuras
2.1.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Union - Find
struct UnionFind{
int p[MAX], r[MAX], setSize[MAX];
int n, numSets;
UnionFind(int _N){
reset(_N);
}
void reset(int N){
n = N;
numSets = n;
for(int i = 0; i <= n; i++){
p[i] = i;
r[i] = 0;
setSize[i] = 1;
}
}
int Find(int i){return (p[i] == i)?i:(p[i] = Find(p[i]));}
bool sameComponent(int i, int j){return Find(i) == Find(j);}
void Union(int i, int j){
if(!sameComponent(i, j)){
numSets--;
int x = Find(i), y = Find(j);
if(r[x] > r[y]){
p[y] = x;
setSize[x] += setSize[y];
} else
{
p[x] = y;
setSize[y] += setSize[x];
if (r[x] == r[y]) r[y]++;
}
}
}
int numDisjointSets(){
return numSets;
}
int sizeOfSet(int i){
return setSize[Find(i)];
}
};
CAPTULO 2. ESTRUCTURAS
2.2.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <cstring>
using namespace std;
#define MAXN 1000000
int
int
int
int
T[MAXN + 1];
A[MAXN];
N;
lowbit(int i) {
return (i & -i);
}
int sum(int i){
int value = 0;
for(; i > 0; i-= lowbit(i))
value+= T[i];
return value;
}
int sum(int i, int j){
return i > 1 ? sum(j) - sum(i-1) : sum(j);
}
void update(int i, int value){
for(; i <= N ; i += lowbit(i))
T[i] += value;
}
void build(){
memset(T, 0, sizeof(T));
for(int i=0; i < N; i++)
update(i+1, A[i]);
}
int main(){
cin >> N;
for(int i = 0; i < N; ++i)
cin >> A[i];
build();
cout << sum( 1, N ) << endl;
return 0;
}
2.3.
1
2
3
4
5
6
7
8
9
10
11
BIT
Segment Tree
#include <ctime>
#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;
int c[100000];
int tree[400001];
//si es segment tree de -,* o / solo sustituir el + en init query y update
void init(int node,int a,int b)
{
if(a==b)
CAPTULO 2. ESTRUCTURAS
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
{
tree[node]=c[a];
return ;
}
init(2*node+1,a,(a+b)/2);
init(2*node+2,(a+b)/2+1,b);
tree[node]=tree[2*node+1]+tree[2*node+2];
}
// consula para llamar query(0,0,n-1,desde,hasta)
int query(int node,int a,int b,int p,int q)
{
//la consulta se hace en el rango desde p a q, a y b son los limites del
rango
if( q<a || b<p )return 0;
if(p<=a && b<=q)
{
return tree[node];
}
return query(2*node+1,a,(a+b)/2,p,q)+query(2*node+2,(a+b)/2+1,b,p,q);
}
//sustituir para llamar(0,0,n-1,posicion,valor)
void update(int node,int a,int b,int p,int val)
{
if(p<a || b<p)return;
if(a==b)
{
tree[node]=val;
return ;
}
update(2*node+1,a,(a+b)/2,p,val);
update(2*node+2,(a+b)/2+1,b,p,val);
tree[node]=tree[2*node+1]+tree[2*node+2];
}
int main()
{
int n,aux;
for(int i=0; i<n; i++)
{
scanf(" %d",&aux);
c[i]=aux;
}
init(0,0,n-1);
//ejemplo de sustitucion tree[a]=val
int a,b;
int val;
scanf(" %d %d",&a,&val);
a--;//solo si los subindices del problema van de 1...n
update(0,0,n-1,a,val);
//ejemplo de consulta x=SUM(a,a+1,....,b)
scanf(" %d %d",&a,&b);
a--;//solo si los subindices del problema van de 1...n
b--;//solo si los subindices del problema van de 1...n
int x=query(0,0,n-1,a,b);
printf(" %d\n",x);
printf("\n");
return 0;
}
CAPTULO 2. ESTRUCTURAS
2.4.
1
2
3
4
5
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
CAPTULO 2. ESTRUCTURAS
6
7
8
9
10
11
12
struct Node{
long long sum; //suma de hijos
long long offset;//suma que no propaga de total nodo
}Tree[500000];
void Update(long long node,long long lo,long long hi,long long i,long long j,
long long val){
13
if(lo>j || hi<i)
14
return;
15
16
17
18
19
20
21
22
23
24
25
26
27
long long Query(long long node,long long lo,long long hi,long long i,long long j
,long long offst){
28
if(lo>j || hi<i)
29
return 0;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
2.5.
1
2
3
Trie
#include <iostream>
#include <vector>
#include <algorithm>
CAPTULO 2. ESTRUCTURAS
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <cstdio>
#include <fstream>
using namespace std;
struct Trie{
Trie* hijos[26];
bool esfin;
vector<int> idhijos;
Trie(){
esfin = false;
for(int i = 0; i < 26; ++i)
hijos[i] = NULL;
}
};
void insertar(Trie* v, char* c){
if(c[0] == \0)
v->esfin = true;
else{
int k = c[0] - a;
if(v->hijos[k] == NULL){
v->hijos[k] = new Trie();
(v->idhijos).push_back(k);
}
insertar(v->hijos[k], c+1);
}
}
void ordenarids(Trie *t){
sort((t->idhijos).begin(), (t->idhijos).end());
int tam = (t->idhijos).size();
for(int i = 0; i < tam; i++){
int k = t->idhijos[i];
ordenarids(t->hijos[k]);
}
}
bool haysol = false;
int tmp, caso;
char vacio[25]="";
string cad;
void mostrar(Trie* v, string p, char* pr){
if(pr[0] == \0){
if(v->esfin){
haysol = true;
puts(p.c_str());
}
int tam = (v->idhijos).size();
for(int i = 0; i < tam; ++i){
int k = v->idhijos[i];
mostrar(v->hijos[k], p + ((char)(a+k)), vacio);
}
}
else{
int k = pr[0] - a;
if(v->hijos[k] != NULL){
bool aux = (v->hijos[k])->esfin;
(v->hijos[k])->esfin = false;
mostrar(v->hijos[k], p, pr+1);
CAPTULO 2. ESTRUCTURAS
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
(v->hijos[k])->esfin = aux;
}
}
}
int main(){
//freopen("entrada.in","r",stdin);
Trie* t;
t = new Trie();
scanf(" %d", &tmp);
char cadena[25];
while(tmp--){
scanf(" %s", cadena);
insertar(t, cadena);
}
ordenarids(t);;
cin >> tmp;
for(caso = 1; caso <= tmp; caso++){
scanf(" %s", cadena);
cad = cadena;
haysol = false;
printf("Case # %d:\n", caso);
mostrar(t, cad, cadena);
if(!haysol)
puts("No match.");
}
return 0;
}
2.6.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
struct nodo{
int valor;
nodo* izq;
nodo* der;
nodo(){
valor = (1<<30);
izq = NULL;
der = NULL;
}
nodo(int _v){
valor = _v;
izq = NULL;
der = NULL;
}
};
void insertar(int val, nodo **n){
if((*n) == NULL)
*n = new nodo(val);
else
if(val > (*n)->valor)
insertar(val, &((*n)->der));
else
insertar(val, &((*n)->izq));
10
CAPTULO 2. ESTRUCTURAS
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
}
void inorden(nodo *n){
if(n != NULL){
inorden(n->izq);
cout << (n->valor) <<" ";
inorden(n->der);
}
}
int main(){
nodo *raiz;
raiz = NULL;
int nro,tmp;
cin >> nro;
while(nro--){
cin >> tmp;
insertar(tmp, &raiz);
}
cout << "IN-ORDEN" << endl;
inorden(raiz);
return 0;
}
11
Captulo 3
Complete Search
3.1.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
int nrosol, f, c;
int sol[10];
bool sePuede(int fila, int col){
if(col != c &&fila == f)return false;
for(int i = col - 1 ; i >= 1; i--)
if(sol[i] == fila || (abs(sol[i] - fila) == abs(i - col)))
return false;
return true;
}
void solve(int col){
if(col == 9){
if(sol[c] == f){
printf(" %2d
%d", nrosol++, sol[1]);
for(int i = 2; i <= 8; i++)
printf(" %d", sol[i]);
printf("\n");
}
return ;
}
for(int i = 1; i <= 8; i++)
if(sePuede(i, col)){
sol[col] = i;
solve(col + 1);
}
}
int main(){
int T; cin >> T;
while(T--){
printf( "SOLN
COLUMN\n #
1 2 3 4 5 6 7 8\n\n" );
cin >> f >> c;
scanf(" %d %d", &f, &c);
nrosol = 1;
memset(sol, 0, sizeof(sol));
sol[c] = f;
solve(1);
}
return 0;
}
12
3.2.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public:
int ans, lim;
void solve(int row, int ld, int rd) {
if (row == lim) { // have placed row queens
ans ++; // we have a solution
return;
}
int pos = lim & (~(row | ld | rd)); // valid positions
while (pos != 0) {
int p = pos & (-pos); // rightmost position
pos -= p; // have tried this
solve(row + p, (ld + p) << 1, (rd + p) >> 1);
}
}
int totalNQueens(int n) {
ans = 0;
lim = (1 << n) - 1;
solve(0, 0, 0);
return ans;
}
};
13
Captulo 4
Divide y venceras
4.1.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
4.2.
1
2
3
4
5
4.3.
MergeSort
Primera implementacion:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
//Entrada: Un array
//Salida: El vector "array" ordenado
//
La cantidad optima de intercambios
int array[MAXN];
int temp[MAXN];
int intercambios = 0;
int d = 0;
void mergesort(int inicio, int length) {
15
16
if(length<=1)
return;
mergesort(inicio, length/2);
mergesort(inicio+length/2, length-length/2);
int i = inicio;
int j = inicio+length/2;
int n = 0;
while(i<inicio+length/2 && j<inicio+length)
if(array[i]<array[j]) {
temp[n++] = array[i++];
intercambios+=d; //para contar los intercambios
} else {
temp[n++] = array[j++];
d++;
}
while(i<inicio+length/2) {
temp[n++] = array[i++];
intercambios+=d;
}
while(j<inicio+length)
temp[n++] = array[j++];
memcpy(array+inicio, temp, length*sizeof(int));
}
4.4.
Si generamos los subconjuntos de una lista de N elementos; sabemos que existen 2N subconjuntos, pero esta complejidad es demasiado cuando N es grande, digamos (N>20).
Problema.- Dado una secuencia de N (1<= N <=34) nmeros, determinar cuntos subconjuntos de esta secuencia tiene
una suma entre A y B.
Esta tcnica consiste en dividir en dos listas por la mitad, Luego generamos las sumatorias de los subconjuntos de
cada lista y los ordenamos. Luego combinar ambos resultados.
Considerare la sumatoria de conjunto vacio como 0.
Ejemplo:
L= { 2 , 5 , 6 , 1, 9};
A=5, B=15
Los dividimos en los listas por la mitad.
X= { 2 , 5, 6}
Y= { 1 , 9}
Generamos los subconjuntos de cada lista.
X = { 0, 2, 5 , {2,5}, 6,{2,6}, {5,6} ,{2,5,6} }
Y= { 0, 1, 9, {1,9} }
Sumatorias de cada subconjunto de manera ordenada.
X= {0,2,5,6,7,8,11,13}
Y= {0,1,9,10}
Combinar resultados
Tenemos que recorrer la lista X y ver cunto nos falta para llegar al intervalo [A, B].
Si el primer elemento de X tenemos 0 entonces en la lista Y tenemos que buscar cuantos elementos existen entre
5 y 15.
Si el segundo elemento de X tenemos 2 entonces en la lista Y buscamos cuantos existen entre 3 y 13.
17
x
Si bien se dan cuenta es muy importante tener ambas listas de una manera ordenada para poder buscar cuantos elementos existen en la segunda matriz entre ese intervalo.
El algoritmo sigue buscando hasta terminar con el ltimo elemento de la primera lista.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <vector>
#include <algorithm>
#include <iostream>
#define all(v) (v).begin(),(v).end()
#define rall(v) (v).rbegin(),(v).rend()
#define sz size()
using namespace std;
vector<int>A,B;
void subsets(vector<int> v, vector<int>&ans){
ans.clear();
int n=v.sz;
for(int mask=0;mask<(1<<n);mask++){
int sum=0;
for(int j=0;j<v.sz;j++)if(mask&(1<<j))sum+=v[j];
ans.push_back(sum);
}
sort(all(ans));
}
int main(){
int N,X,Y,n,nx;
cin>>N>>X>>Y;
vector<int>v(N);
for(int i=0;i<N;i++)cin>>v[i];
n=N/2;
subsets(vector<int>(v.begin(),v.begin()+n),A);
subsets(vector<int>(v.begin()+n,v.end()),B);
long long ans=0;
for(int i=0;i<A.sz;i++){
int val=A[i];
int frs=X-val;
int scd=Y-val;
int x1=lower_bound(all(B),frs)-B.begin();
int y1=upper_bound(all(B),scd)-B.begin();
if(y1>=x1)ans+=(y1-x1);
}
cout<<ans<<endl;
return 0;
}
Captulo 5
Programacin Dinamica
5.1.
Subset Sum:
(
OP T (j 1, W )
(wj > W )
OP T (j, W ) = max
wj + OP T (j 1, W wj ) (wj W )
0-1 Mochila
(
OP T (j 1, W )
OP T (j, W ) = max
vj + OP T (j 1, W wj )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
(wj > W )
(wj W )
/*
Nota:
Si los pesos son muy grandes o el valor de llenar la mochila es muy grande
se puede utilizar un map en vez de una matriz para la memoizacion
*/
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
long long int lib;
bool sel[35][1005], sol[35];//para reconstruccion (*)
int cant ; // * cantidad de elementos tomados
long long int dp[35][1005], v[35], p[35];//dp[OBJETOS + 1][LIBRE
long long int mochila(int i, int libre) { // Llamar mochila(N-1,
if(i < 0)return 0LL;
long long int &ans = dp[i][libre];
if(ans != -1) return ans;
ans = mochila(i-1, libre);// no lo tomo
if(p[i] <= libre) { // si cabe en el espacio disponible
ans = max(ans ,v[i] + mochila(i-1, libre - p[i])); // pruebo
if(ans == v[i] + mochila(i-1, libre - p[i]))//si se tomo el
sel[i][libre] = true;// marco como tomado (*)
}
return ans;
}
+ 1]
libre)
si lo tomaria
objeto (*)
5.2.
1
2
3
4
5
6
7
8
El problema de la mochila(iterativo)
/*
Nota:
-Tomar en cuenta que para calcular la fila i solo se necesita la fila i-1
entonces,
si el problema utiliza demasiada memoria o no entra se puede hacer el mismo
procedimiento
con solo 2 vectores llenando la fila actual con la fila ya calculada
y luego actual.swap(anterior), para todas la filas
- La version recursiva corre mas rapido por que no es necesario llenar toda la
matriz dp
9 */
10 #include <cstdio>
11 #include <algorithm>
12 #include <cstring>
13
14
15
16
17
18
19
20
21
22
23
24
19
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
return dp[n][libre];
}
void reconstruir(int n, int libre) {
int j = libre;
cant = 0;
memset(sol, false, sizeof(sol));
for(int i = n; i >= 1; i--)
if(sel[i][j] == 1) {
sol[i-1] = true;
cant++;
j = j - p[i-1];
}
}
int main() {
int n;
scanf(" %d %lld", &n, &lib);//N objetos y LIV espacio de la mochila
for(int i = 0; i < n; i++)
scanf(" %lld %lld", &p[i], &v[i]);
memset(dp, -1, sizeof(dp));
memset(sel, false, sizeof(sel));//para reconstruccion (*)
printf(" %lld\n", mochila(n, lib));
reconstruir(n, lib);
printf(" %d\n", cant);
for(int i = 0; i < n; i++)
if(sol[i])
printf(" %lld %lld\n", p[i], v[i]);
return 0;
}
5.3.
1
2
3
4
5
6
7
8
9
20
Cambio de modenas
5.4.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
vector<long long int> v;
vector<long long int> ancho;
vector<long long int> dp;
int t, n;
long long int lis(int i) {
if(i == 0)return ancho[0];//(*) si no es pesado 1
long long int ans = dp[i];
if(ans != -1LL) return ans;
ans = ancho[i];//(*) 1
for(int j = 0; j < i; j++)
if(v[j] < v[i]) // si no es estrictamente creciente "<="
ans = max(ans, ancho[i] + lis(j)); // 1 + lis(j)
return dp[i] = ans;
}
int solve() {
(vector<long long int>(n, -1LL)).swap(dp);
long long int ans = 0;
for(int i = n-1; i >= 0; i--)
ans = max(ans, lis(i));
return ans;
}
int main() {
scanf(" %d", &n);
(vector<long long int>(n)).swap(v);
(vector<long long int>(n)).swap(ancho);
for(int i = 0; i < n; i++)
scanf(" %lld", &v[i]);
for(int i = 0; i < n; i++)//si es pesado
scanf(" %lld", &ancho[i]);//
printf("lis = %d\n", solve());
return 0;
}
5.5.
1
2
3
4
5
6
7
8
9
10
11
LIS (O(n2 ))
#include <algorithm>
#include <cstdio>
#include <stack>
using namespace std;
#define MAX_N 100000
void imprimir(int end, int a[], int p[]) {
int x = end;
stack<int> s;
for (; p[x] >= 0; x = p[x]) s.push(a[x]);
21
5.6.
1
2
3
4
5
6
7
8
9
10
11
12
//Algoritmo de kadane
//Entrada: Un vector de numero enteros
//Salida : La suma maxima de alguno de rangos en O(n)
long long int maxrangesum(vector<int> &v) {
long long int sum = 0, ans = -(1LL<<60);//la maxima suma podria ser negativa
for(int i = 0; i < v.size(); i++) {
sum += v[i];
ans = max(ans, sum);
if(sum < 0) sum = 0;
}
return ans;
}
5.7.
1
2
3
4
5
6
7
8
9
10
#include <cstdio>
#include <algorithm>
#define MAX 103
using namespace std;
int v[MAX][MAX] = {0};
int main() {
int n, tmp;
scanf(" %d", &n);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++) {
22
5.8.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <algorithm>
#include <cstdio>
using namespace std;
int n, A[101][101] = {0}, maxSubRect, subRect;
int main() { // O(n^3) 1D DP + greedy (Kadane) solucion
scanf(" %d", &n);
// La dimension de la matriz
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
scanf(" %d", &A[i][j]);
A[i][j] += A[i][j - 1]; // vamos acumulando de fila en fila
}
maxSubRect = -127*100*100; // El valor mas bajo para la respuesta
for (int l = 1; l <= n; l++)
for (int r = l; r <= n; r++) {
subRect = 0;
for (int row = 1; row <= n; row++) {
// Max 1D Range Sum en las columnas de la fila i
subRect += A[row][r] - A[row][l - 1];
// El algoritmo de Kadane en las filas
if (subRect < 0) subRect = 0;
// golosamente, reiniciamos si sum < 0
maxSubRect = max(maxSubRect, subRect);
}
}
printf(" %d\n", maxSubRect);
return 0;
}
5.9.
1
2
3
4
5
6
7
8
23
#include <vector>
#include <iostream>
#include <stack>
using namespace std;
int main(){
int n, m;
cin >> n >> m;
vector < vector<char> > a (n, vector<char> (m));
5.10.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
24
5.11.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
25
#include
#include
#include
#include
5.12.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <cstdio>
#include <cstring>
#define MAXS 2005
#define max(a,b) a>b?a:b
#define min(a,b) a<b?a:b
using namespace std;
char a[MAXS], b[MAXS];
int ta, tb;
int casos;
int dp[MAXS][MAXS];
int solve(int ta, int tb){
if(ta < 0 && tb < 0)
return 0;
if(ta < 0)
return tb + 1;
if(tb < 0)
return ta + 1;
int &ans = dp[ta][tb];
if(ans == -1){
ans = 1<<30;
if(a[ta] == b[tb] )
ans = min(ans, solve(ta - 1, tb - 1));
else
ans = min(ans, 1 + solve(ta - 1, tb - 1));// con un solo cambio
convierto en lo mismo
ans = min(ans, 1 + solve(ta - 1, tb
));
ans = min(ans, 1 + solve(ta
, tb - 1));
}
return ans;
}
int main(){
//freopen("entrada.in", "r", stdin);
scanf(" %d", &casos);
while(casos--){
scanf(" %s %s", a, b);
ta = strlen(a);
tb = strlen(b);
memset(dp, -1, sizeof(dp));
printf(" %d\n",solve(ta-1, tb - 1));
}
return 0;
}
26
Captulo 6
Grafos
6.1.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <queue>
#include <vector>
#include <cstring>
#define MAXN 1000
using namespace std;
vector<int> grafo[MAXN];
int d[MAXN];
queue<int> cola;
void BFS(int ini){
memset(d,-1, sizeof d);
cola.push(ini);
d[ini] = 0;
while(!cola.empty()){
int act = cola.front();cola.pop();
for(int i = 0; i < grafo[act].size(); i++){
int ady = grafo[act][i];
if(d[ady] == -1){
d[ady] = d[act] + 1;
cola.push(ady);
}
}
}
}
6.2.
1
2
3
4
5
6
7
8
9
BFS
DFS
CAPTULO 6. GRAFOS
10
11
12
13
14
15
16
17
18
19
28
visitado[i][j] = true;
for(int k=0; k<8; k++) {
int a = di[k] + i;
int b = dj[k] + j;
if(a >= 0 && b >= 0 && a < n && b < n &&!visitado[a][b]) {
if(mat[a][b]==pain) ff_dfs(a,b);
else visitado[a][b]=true;
}
}
}
6.3.
Topological Sort
6.4.
1
2
3
4
5
6
7
Dijkstra
for(int i = 0; i < nodos; ++i){
d[i] = INF;
v[i] = false;
}
d[ini] = 0;
q.insert(make_pair(0,ini));
while(!q.empty()){
CAPTULO 6. GRAFOS
act = (*(q.begin())).second;q.erase(q.begin());
if(v[act])continue;
v[act] = true;
for(int i = 0; i < grafo[act].size(); ++i){
ady = grafo[act][i].first;
peso = grafo[act][i].second;
if(!v[ady] && d[act] + peso < d[ady] ){
d[ady] = d[act] + peso;
q.insert(make_pair(d[ady],ady));
}
}
8
9
10
11
12
13
14
15
16
17
18
19
20
21
}
if(d[fin] != INF) cout << d[fin] << endl;
else cout << "unreachable" << endl;
6.5.
BellmandFord
Si un grafo contiene un ciclo de coste total negativo entonces este grafo no tiene solucin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include
#include
#include
#include
#include
<cstdio>
<algorithm>
<cstring>
<vector>
<fstream>
29
CAPTULO 6. GRAFOS
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
6.6.
1
2
3
4
5
6
7
8
Floyd Warshall
30
CAPTULO 6. GRAFOS
6.7.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include
#include
#include
#include
#include
#include
#include
<cstring>
<string>
<cstdio>
<cstdlib>
<vector>
<algorithm>
<iostream>
31
CAPTULO 6. GRAFOS
6.8.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include
#include
#include
#include
<cstdio>
<vector>
<cstring>
<fstream>
32
CAPTULO 6. GRAFOS
57
58
59
60
61
}
printf(" %d\n", kosaraju()==1);
}
return 0;
}
6.9.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
typedef long long lli;
typedef pair<int, int> pii;
#define LENGTH(a) ((int)a.length())
#define SIZE(a) ((int)a.size())
int const MAX = 100;
int const INF = 1000000;
class Grafo
{
public:
vector<vector<int> > L;
vector<int> num, low;
vector<bool> visitado;
vector<int> componente;
int nComponentes, numCnt;
Grafo(int n)
{
init(n);
}
void init(int n)
{
L = vector<vector<int> >(n);
num = vector<int>(n, -1);
low = vector<int>(n, 0);
visitado = vector<bool>(n, false);
componente.clear();
nComponentes = numCnt = 0;
}
void add(int a, int b)
{
L[a].push_back(b);
}
void ejecutarTarjan()
{
for (int i = 0; i < SIZE(L); ++i)
if (num[i] == -1)
tarjan(i);
}
33
CAPTULO 6. GRAFOS
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
void tarjan(int u)
{
low[u] = num[u] = numCnt++;
visitado[u] = true;
componente.push_back(u);
for (int i = 0; i < SIZE(L[u]); ++i)
{
int v = L[u][i];
if (num[v] == -1)
tarjan(v);
if (visitado[v])
low[u] = min(low[u], low[v]);
}
if (num[u] == low[u])
{
nComponentes++;
int v;
do
{
v = componente[SIZE(componente) - 1];
visitado[v] = false;
componente.erase(--componente.end());
}
while (v != u);
}
}
};
int main(){
int nodos;
cin>>nodos;
Grafo g(nodos);
//leer lados
g.ejecutarTarjan();
//g.nComponentes contiene el numero de SCC
return 0;
}
Otra implementacion:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.util.*;
public class SCCTarjan {
int time;
List<Integer>[] graph;
int[] lowlink;
boolean[] used;
List<Integer> stack;
List<List<Integer>> components;
public List<List<Integer>> scc(List<Integer>[] graph) {
int n = graph.length;
this.graph = graph;
lowlink = new int[n];
used = new boolean[n];
stack = new ArrayList<>();
components = new ArrayList<>();
34
CAPTULO 6. GRAFOS
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
6.10.
1
2
3
4
5
6
7
8
9
35
CAPTULO 6. GRAFOS
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
6.11.
#include
#include
#include
#include
#include
#include
<cstdio>
<fstream>
<algorithm>
<vector>
<cmath>
<climits>
36
CAPTULO 6. GRAFOS
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
37
CAPTULO 6. GRAFOS
6.12.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
Minimum Cut
#include <iostream>
#include <limits.h>
#include <string.h>
#include <queue>
using namespace std;
#define V 100
int bfs(int rGraph[V][V], int s, int t, int parent[])
{
bool visited[V];
memset(visited, 0, sizeof(visited));
queue <int> q;
q.push(s);
visited[s] = true;
parent[s] = -1;
while (!q.empty())
{
int u = q.front();
q.pop();
for (int v=0; v<V; v++)
{
if (visited[v]==false && rGraph[u][v] > 0)
{
q.push(v);
parent[v] = u;
visited[v] = true;
}
}
}
return (visited[t] == true);
}
void dfs(int rGraph[V][V], int s, bool visited[])
{
visited[s] = true;
for (int i = 0; i < V; i++)
if (rGraph[s][i] && !visited[i])
dfs(rGraph, i, visited);
}
void minCut(int graph[V][V], int s, int t)
{
int u, v;
int rGraph[V][V];
for (u = 0; u < V; u++)
for (v = 0; v < V; v++)
rGraph[u][v] = graph[u][v];
int parent[V];
while (bfs(rGraph, s, t, parent))
{
int path_flow = INT_MAX;
for (v=t; v!=s; v=parent[v])
{
u = parent[v];
path_flow = min(path_flow, rGraph[u][v]);
38
CAPTULO 6. GRAFOS
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
}
for (v=t; v != s; v=parent[v])
{
u = parent[v];
rGraph[u][v] -= path_flow;
rGraph[v][u] += path_flow;
}
}
bool visited[V];
memset(visited, false, sizeof(visited));
dfs(rGraph, s, visited);
int costoCorte=0;
for (int i = 0; i < V; i++)
for (int j = 0; j < V; j++)
if (visited[i] && !visited[j] && graph[i][j]){
//cout << i << " - " << j << endl;
costoCorte+=graph[i][j];
}
cout<<costoCorte<<endl;
return;
}
int main()
{
int graph[V][V];
minCut(graph, 0, 5);
return 0;
}
6.13.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
MaxFlow
#include
#include
#include
#include
#include
<algorithm>
<cstring>
<cstdio>
<limits>
<queue>
39
CAPTULO 6. GRAFOS
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
6.14.
1
2
3
4
5
6
7
8
9
10
11
12
#include <cctype>
#include <cstdio>
#include <iostream>
#define NN 100048
using namespace std;
// LCA con pesos
// halla camino corto desde a hasta b con numero de consultas q
int P[NN][17], L[NN];
long long W[NN];
40
CAPTULO 6. GRAFOS
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
6.15.
1
2
3
4
5
6
7
8
#include <cstdio>
#include <list>
#include <queue>
//Emparejamiento Bipartito hasta 50000 nodos y 150000 caminos :) crazy...
using namespace std;
//MAX_N y SINK son mayores al numero de nodos
41
CAPTULO 6. GRAFOS
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
42
CAPTULO 6. GRAFOS
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
}
dist[u] = INFINITO;
return false;
}
int hopcroft_karp() {
int matching = 0;
for (int i = 0;
grafo1[i] =
}
for (int j = 0;
grafo2[j] =
}
i < N; ++i) {
SINK;
j < M; ++j) {
SINK;
while (bfs()) {
for (int i = 0; i < N; ++i) {
if (grafo1[i] == SINK) {
matching += dfs(i);
}
}
}
return matching;
}
int main() {
// inside in main() ggg al estilo halim
//N primer conjunto
//M segundo conjunto
//P numero de relaciones (arcos)
scanf(" %i %i %i", &N, &M, &P);
//clear
for (int i = 0; i < N; ++i) {
adj[i] = list< int >();
}
for (int i = 0; i < P; ++i) {
int u, v;
scanf(" %i %i", &u, &v);
--u; --v;
adj[u].push_back(v);
}
printf(" %i\n", hopcroft_karp());
return 0;
}
6.16.
1
2
3
4
5
6
43
Puentes
import java.util.*;
public class Bridges {
static int time;
static List<Integer>[] graph;
CAPTULO 6. GRAFOS
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
static
static
static
static
6.17.
1
2
3
4
5
6
7
8
9
10
11
12
13
boolean[] used;
int[] tin;
int[] lowlink;
List<String> bridges;
Puntos de Articulacin
import java.util.*;
public class ArticulationPoints {
static
static
static
static
static
static
int time;
List<Integer>[] grafo;
boolean[] vis;
int[] tin;
int[] dfsLow;
List<Integer> puntosArticulacion;
44
CAPTULO 6. GRAFOS
dfsLow[u] = tin[u] = time++;
int child = 0;
for (int v : grafo[u]) {
if (v == p) {
continue;
}
if (vis[v]) {
dfsLow[u] = Math.min(dfsLow[u], tin[v]);
} else {
dfs(v, u);
dfsLow[u] = Math.min(dfsLow[u], dfsLow[v]);
if (dfsLow[v] >= tin[u] && p != -1) {
puntosArticulacion.add(u);
}
++child;
}
}
if (p == -1 && child > 1) {
puntosArticulacion.add(u);
}
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
}
public static void main(String[] args) {
time = 0;
int n = 5;
grafo = new List[n];
for (int i = 0; i < n; i++) {
grafo[i] = new ArrayList<>();
}
vis = new boolean[n];
tin = new int[n];
dfsLow = new int[n];
puntosArticulacion = new ArrayList<>();
dfs(0, -1);
//System.out.println(puntosArticulacion); si puntosArticulacion == null
entonces es un grafo biconexo
}
}
6.18.
1
2
3
4
5
6
7
8
9
10
11
12
13
Camino Euleriano
list<int> cyc;
void EulerTour(list<int>::iterator i, int u){
for(int j = 0; j < grafo[u].size(); j++){
pair<int,int> v = grafo[u][j];
if(v.second){
v.second = 0;
for(int k = 0; k < grafo[v.first].size(); k++){
pair<int,int> uu = grafo[v.first][k];
if(uu.first == u && uu.second){
uu.second = 0;
break;
}
}
45
CAPTULO 6. GRAFOS
14
15
16
17
18
19
20
21
22
23
24
6.19.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Dijkstra Fast
46
Captulo 7
Matemticas
7.1.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
7.2.
1
2
3
4
5
LCM
7.3.
1
2
3
4
5
GCD
CAPTULO 7. MATEMTICAS
6
7
8
9
10
11
12
7.4.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Exponenciacin rapida
7.5.
1
2
3
4
5
6
7
8
9
10
11
12
13
48
Criba de Erathostenes
#include <vector>
#include <bitset>
#define MAXPRIME 3162300 // raiz de maximo numero que manejaremos
using namespace std;
bitset<MAXPRIME> criba;
vector<long long int> primos;
void llena_criba()
{
criba.set();// marcamos todo como false
CAPTULO 7. MATEMTICAS
14
15
16
17
18
19
20
21
7.6.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
7.7.
1
2
3
4
5
6
7
8
9
10
11
12
13
Triangulo de Pascal
7.8.
1
2
3
49
CAPTULO 7. MATEMTICAS
4
5
6
7
8
9
10
7.9.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
Polinomios
class Polinomio {
double[] coef;
// a0 + a1x + a2x^2 + ...
public Polinomio(double[] coef) {
this.coef = coef;
}
public double integrar(double a, double b) {
Polinomio integ = integral();
return integ.evaluar(b) - integ.evaluar(a);
}
public double evaluar(double x) {
double result = 0;
for (int i = coef.length - 1; i >= 0; i--)
result = coef[i] + x*result;
return result;
}
public Polinomio integral() {
double[] newCoef = new double[coef.length + 1];
newCoef[0] = 0;
for (int i = 1; i < newCoef.length; i++)
newCoef[i] = coef[i-1]/i;
return new Polinomio(newCoef);
}
public Polinomio cuadrado() {
double[] newCoef = new double[coef.length * 2 - 1];
for (int i = 0; i < newCoef.length; i++)
for (int j = 0; j <= i; j++)
if (j < coef.length && i - j < coef.length)
newCoef[i] += coef[j] * coef[i-j];
return new Polinomio(newCoef);
}
public Polinomio multiplicar(double c) {
double[] newCoef = new double[coef.length];
for (int i = 0; i < newCoef.length; i++)
newCoef[i] = coef[i] * c;
return new Polinomio(newCoef);
}
}
50
CAPTULO 7. MATEMTICAS
7.10.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//Entrada: Un entero n
//Salida: El n-esimo fibonacci en tiempo O(log(n))
long long int fibo(int n) {
long long int a,b,x,y,tmp;
a = x = tmp = 0;
b = y = 1;
while(n!=0)
if(n %2 == 0) {
tmp = a*a + b*b;
b = b*a + a*b + b*b;
a = tmp;
n = n/2;
} else {
tmp = a*x + b*y;
y = b*x + a*y + b*y;
x = tmp;
n = n-1;
}
// x = fibo(n-1)
return y;// y = fibo(n)
}
7.11.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Fibonacci ( O(log(n)) )
51
CAPTULO 7. MATEMTICAS
31
32
33
34
35
36
37
38
multi(m);
string r(res);
string sal(r.rbegin(), r.rend());
cout << sal << endl;
return 0;
}
7.12.
//Entrada: 2 BigIntegers x e y
//Salida: La multplicacion de x e y
import java.math.BigInteger;
class Karatsuba {
private final static BigInteger ZERO = new BigInteger("0");
public static BigInteger karatsuba(BigInteger x, BigInteger y) {
int N = Math.max(x.bitLength(), y.bitLength());
if (N <= 2000) return x.multiply(y);
N = (N / 2) + (N % 2);
BigInteger b = x.shiftRight(N);
BigInteger a = x.subtract(b.shiftLeft(N));
BigInteger d = y.shiftRight(N);
BigInteger c = y.subtract(d.shiftLeft(N));
BigInteger ac = karatsuba(a, c);
BigInteger bd = karatsuba(b, d);
BigInteger abcd = karatsuba(a.add(b), c.add(d));
return ac.add(abcd.subtract(ac).subtract(bd).shiftLeft(N)).add(bd.
shiftLeft(2*N));
18
}
19 }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
7.13.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Integracion de Simpson
double a[12];
int n;
double f(double x){
double ans = 0;
for(int i = 0; i <= n; i++)
ans += (a[i] * pow(x,i));
return ans*ans*PI;
}
double S(double a, double b, double c, double h){
return (h / 3.0) * ( f(a) + 4.0 * f(c) + f(b));
}
double SIMP(double a, double b, double E ){
double h = (b-a)/2.0,
c = (b+a)/2.0;
double a1 = a,
a2 = c,
b1 = c,
b2 = b;
52
CAPTULO 7. MATEMTICAS
21
22
23
24
25
26
27
28
29
double c1 = (b1+a1)/2.0,
c2 = (b2+a2)/2.0;
double L = (S(a1,b1, c1,h) + S(a2,b2,c2,h)) / 2.0;
if(0.1*abs(L-S(a,b,c,h)) < E)
return L;
else
return SIMP(a1,b1, E/2.0) + SIMP(a2,b2, E/2.0);
}
7.14.
Inverso modular
7.15.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <cstdio>
int main() {
int N;
while (scanf(" %d", &N) && N) {
int b = 0;
while (N--) {
int v;
scanf(" %d", &v);
b ^= v;
}
puts(b ? "Yes" : "No");
}
return 0;
}
7.16.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
El juego de Nim
Fraccion
/////////////////////////////////////////////////////////////////////
//Fraction.
/////////////////////////////////////////////////////////////////////
using namespace std;
typedef long long Num;
Num gcd(Num a, Num b) {
Num temp;
if (a < b) {
temp = a;
a = b;
b = temp;
53
CAPTULO 7. MATEMTICAS
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
}
do {
temp = a % b;
a = b;
b = temp;
} while (b != 0);
return a;
}
struct Fraction {
Num up;
Num down;
Fraction(Num _up = 1, Num _down = 1) {
up = _up;
down = _down;
}
void reduce() {
if (up != 0) {
Num div = up > 0? gcd(up, down): gcd(-up, down);
up /= div;
down /= div;
}
else {
down = 1;
}
}
Fraction operator + (const Fraction& add) const {
Fraction result(up * add.down + down * add.up, down * add.down);
result.reduce();
return result;
}
Fraction operator - (const Fraction& sub) const {
Fraction result(up * sub.down - down * sub.up, down * sub.down);
result.reduce();
return result;
}
Fraction operator * (const Fraction& mul) const {
Fraction result(up * mul.up, down * mul.down);
result.reduce();
return result;
}
Fraction operator / (const Fraction& div) const {
Fraction result(up * div.down, down * div.up);
result.reduce();
return result;
}
bool operator == (Num i) const {
return up % down == 0 && up / down == i;
}
bool operator != (Num i) const {
54
CAPTULO 7. MATEMTICAS
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
7.17.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Matriz
55
CAPTULO 7. MATEMTICAS
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
7.18.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Gauss Jordan
56
CAPTULO 7. MATEMTICAS
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
}
fraction operator/(const fraction& f) {
fraction ret(n*f.d,d*f.n);
return ret;
}
fraction operator*(const fraction& f) {
fraction ret(n*f.n,d*f.d);
return ret;
}
fraction operator+(const fraction& f) {
fraction ret((n*f.d)+(f.n*d),d*f.d);
return ret;
}
fraction operator*(L x) {
fraction ret(x*n,d);
return ret;
}
fraction operator-() {
fraction ret(-n,d);
return ret;
}
fraction operator-(const fraction& f) {
fraction ret((n*f.d)-(f.n*d),d*f.d);
return ret;
}
bool operator>(const fraction& f) {
return abs(n*f.d)>abs(f.n*d);
}
fraction read(){
char c;
scanf(" %lld",&n);
d = 1;
scanf(" %c",&c);
if(c==/)
scanf(" %lld",&d);
}
void print(){
if(d==1) {
printf(" %lld\n",n);
} else {
printf(" %lld/ %lld\n",n,d);
}
}
};
bool hasSol;
int rankA,rankAC;
const int MX = 59;
vector<fraction> mat[MX];
fraction x[MX];
int N,Y,X,nunk;
void gauss() {
for(int p=1;p<=nunk;p++) {
int maxR=p;
for(int y=p+1;y<=Y;y++)
57
CAPTULO 7. MATEMTICAS
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
58
CAPTULO 7. MATEMTICAS
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
fraction s(0,1);
for(int k=p+1;k<=nunk;++k)
s = s + (x[k]*mat[p][k]);
x[p] = (mat[p][X]-s) / mat[p][p];
}
for(int y=1;y<=nunk;y++)
printf("x[ %d] = ",y),x[y].print();
}
}
}
int main() {
int nc;
bool first=true;
for(int i=0;i<MX;i++)
mat[i].resize(MX);
while(scanf(" %d",&N) and N>0) {
if(first == false) printf("\n");first = false;
printf("Solution for Matrix System # %d\n",N);
resuelva();
}
}
7.19.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
59
Numeros romanos
Captulo 8
Cadenas
8.1.
1
2
3
Utilidades
8.2.
Boyer Moore
#include <iostream>
#include <cstring>
using namespace std;
int M, N;
//M tamanio del patron
//N tamanio del texto
void preBM(char P[], int bmNext[])
{
for(int i = 0; i <= 255; i++)
bmNext[i] = M;
for(int i = 0; i < M; i++)
bmNext[P[i]] = M - 1 - i ;
}
void Boyer_Moore(char T[], char P[])
{
int i = M - 1;
int j = M - 1;
int bmNext[255];
preBM(P,bmNext);
while((i < N) && (j >= 0))
{
if(T[i] == P[j])
{
i--;
j--;
}
60
CAPTULO 8. CADENAS
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
else
{
i += bmNext[T[i]];
j = M - 1;
}
if(j < 0)
{
cout<<"Match en: "<<(i + 1)<<endl;
i += M + 1;
j = M - 1;
}
}
}
int main()
{
char texto[100];
char patron[100];
cin>>texto;
cin>>patron;
M=strlen(patron);
N=strlen(texto);
Boyer_Moore(texto,patron);
return 0;
}
8.3.
61
CAPTULO 8. CADENAS
8.4.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
62
Iesima permutacin
8.5.
Algoritmo de Manacher
El algoritmo guarda el tamao del palindrome mas grande en LP[pos] que tiene como centro las posicin pos en la
cadena original
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <vector>
#include <fstream>
#include <string.h>
#define MAXN 20100
using namespace std;
int N,i,j,izq,der,posi,dist;
string cad,tmp;
char v[MAXN];
int pos[MAXN];
void todoslosPalindromos(vector<int> &LP, int par){
izq = der = -1;
for(posi = 0; posi < N; posi++){
dist = 0;
if(posi <= der)
dist = min(der - posi + par, LP[izq+der-(posi+par)]) + 1;
while(posi-dist>=0 && posi+dist-par<N
&& v[posi-dist]==v[posi+dist-par])
dist++;
LP[posi] = --dist;
if(posi+dist-par > der){
der = posi + dist - 1;
izq = posi - dist ;
}
}
}
int main() {
getline(fin,cad);
while(getline(fin,tmp))
cad +=\n+tmp;
N = 0;
for(i = 0; i < cad.length(); i++)
CAPTULO 8. CADENAS
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
63
if(isalpha(cad[i])){
v[N] = tolower(cad[i]);
pos[N] = i;
N++;
}
v[N] = \0;
vector<int> LP(N,0),LI(N,0);
todoslosPalindromos(LP,1);
todoslosPalindromos(LI,0);
int SOL1 = 0,SOL2 = 0;
//primero en los de tamanio impar
for(int i = 0; i < N; i++)
if(LI[i]*2+1 > LI[SOL1]*2+1)
SOL1 = i;
//luego en los de tamanio par
for(int i = 0; i < N; i++)
if(LP[i]*2 > LP[SOL2]*2)
SOL2 = i;
if(LI[SOL1]*2+1 > LP[SOL2]*2){
izq = SOL1 - LI[SOL1];
der = SOL1 + LI[SOL1];
}else{
izq = SOL2 - LP[SOL2];
der = SOL2 + LP[SOL2]-1;
}
fout << der - izq + 1 <<
endl;
izq = pos[izq];
der = pos[der];
fout << cad.substr(izq,der-izq+1)<<endl;
return 0;
}
Otra implementacion:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CAPTULO 8. CADENAS
23
24
25
26
i = i + k;
j = max(j - k, 0);
}
}
8.6.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int longestCommonSubsequence(const string& a, const string& b) {
int A = a.size(), B = b.size();
int L[2][B + 1];
for (int i = 0; i <= 1; ++i) L[i][0] = 0;
for (int i = 0; i <= B; ++i) L[0][i] = 0;
for (int i = 1; i <= A; ++i) {
int this_i = i % 2, pre_i = this_i ? 0 : 1;
for (int j = 1; j <= B; ++j) {
if (a[i - 1] == b[j - 1]) L[this_i][j] = 1 + L[pre_i][j - 1];
else L[this_i][j] = max(L[pre_i][j], L[this_i][j - 1]);
}
}
return max(L[0][B], L[1][B]);
}
int main() {
string a, b;
cin >> a >> b;
cout << longestCommonSubsequence(a, b);
}
8.7.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Suffix Array
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <cmath>
#include <string>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#include <utility>
#include <list>
#include <set>
#include <map>
using namespace std;
#define MAXN 1000005
64
CAPTULO 8. CADENAS
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
65
CAPTULO 8. CADENAS
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
}
int main(){
freopen("760.in","r",stdin);
bool sw=false;
while(scanf(" %s",&s)==1){
scanf(" %s",&s2);
strcat(s,"$");
tam1=strlen(s);
strcat(s,s2);
strcat(s,"#");
n =strlen(s);
m=strlen(s)-tam1;
suff_arr();
lcp();
int dev=0;
string dev2;
orde.clear();
for(int i=0;i<n;i++){
if(owner(r[i]) != owner(r[i-1])){
//por si quiere mostrat $ o #
if(h[i-1] >= dev){
dev=h[i-1];
//cout<<r[i]<<" --- "<<h[i-1]<<endl;
string aux="",aux2="";
for(int j=0;j<dev;j++){
aux2=s[r[i]+j];
aux+=aux2;
}
orde.insert(aux);
}
}
}
if(sw)
printf("\n");
sw = true;
if(dev == 0)
printf("No common sequence.\n");
else{
set<string>::iterator it=orde.begin();
for (;it!=orde.end(); it++){
if((*it).size()==dev)cout <<*it<< endl;
}
}
}
return 0;
}
//rotacion menor lexicografica
/*
int tam1=strlen(s);
for(int i=tam1;i<2*tam1;i++)s[i]=s[i-tam1];
n=2*tam1;
suff_arr();
char dev[tam1];
for(int i=0;i<n;i++)
if(r[i]<tam1){
for(int j=r[i];j<r[i]+tam1;j++)
dev[j-r[i]]=s[j];
66
CAPTULO 8. CADENAS
135
136
137
138
139
140
141
142
143
144
145
146
147
break;
}
for(int i=0;i<tam1;i++)
printf(" %c",dev[i]);
*/
/*
ACM 2009 File Recover
Solucion
Problema: Contar los substrings q se repiten al menos una vez.
Analisis: Notamos que si el lcp(i,i+1) con lcp(i+1,i+2) aumenta
quiere decir que encontramos h[i+1]-h[i] palabras nuevas (prefijos)
SUM(max(h[i+1]-h[i],0))
*/
8.8.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//from http://blog.csdn.net/acdreamers/article/details/10746023
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
using namespace std;
const int N=250005;
struct State
{
State *pre,*go[26];
int step;
void clear()
{
pre=0;
step=0;
memset(go,0,sizeof(go));
}
}*root,*last;
State statePool[N*2],*cur;
void init()
{
cur=statePool;
root=last=cur++;
root->clear();
}
void Insert(int w)
{
State *p=last;
State *np=cur++;
np->clear();
np->step=p->step+1;
while(p&&!p->go[w])
p->go[w]=np,p=p->pre;
if(p==0)
np->pre=root;
else
67
CAPTULO 8. CADENAS
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
{
State *q=p->go[w];
if(p->step+1==q->step)
np->pre=q;
else
{
State *nq=cur++;
nq->clear();
memcpy(nq->go,q->go,sizeof(q->go));
nq->step=p->step+1;
nq->pre=q->pre;
q->pre=nq;
np->pre=nq;
while(p&&p->go[w]==q)
p->go[w]=nq, p=p->pre;
}
}
last=np;
}
char A[N],B[N];
int main()
{
int n,m;
scanf(" %s %s",A,B);
n=strlen(A);
m=strlen(B);
init();
for(int i=0; i<n; i++)
Insert(A[i]-a);
int ans=0,len=0;
State *p=root;
for(int i=0; i<m; i++)
{
int x=B[i]-a;
if(p->go[x])
{
len++;
p=p->go[x];
}
else
{
while(p&&!p->go[x]) p=p->pre;
if(!p) p=root,len=0;
else
len=p->step+1,p=p->go[x];
}
ans=max(ans,len);
}
printf(" %d\n",ans);
return 0;
}
8.9.
1
2
/*
Rotacion Lexicografica minima MinRotLex(cadena,tamanio)
68
CAPTULO 8. CADENAS
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
8.10.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Trie
#include <iostream>
#include <vector>
using namespace std;
struct Node{
char content;
bool wordMarker;
vector<Node*> children;
Node() { content = ; wordMarker = false; }
void setContent(char c) { content = c; }
void setWordMarker() { wordMarker = true; }
Node* findChild(char c);
void appendChild(Node* child) { children.push_back(child); }
};
struct Trie {
Node* root;
Trie(){root=new Node();}
void addWord(string s);
69
CAPTULO 8. CADENAS
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
bool Trie::searchWord(string s)
{
Node* current = root;
while ( current != NULL )
{
for ( int i = 0; i < s.length(); i++ )
{
Node* tmp = current->findChild(s[i]);
if ( tmp == NULL )
return false;
current = tmp;
}
if ( current->wordMarker )
return true;
else
70
CAPTULO 8. CADENAS
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
return false;
}
return false;
}
int main(){
Trie* trie = new Trie();
trie->addWord("algo");
trie->addWord("ala");
trie->addWord("abeja");
trie->addWord("abel");
trie->addWord("trie");
if ( trie->searchWord("abel") )
cout << "Encontrado" << endl;
else cout << "No encontrado" << endl;
delete trie;
}
8.11.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Aplicaciones
71
CAPTULO 8. CADENAS
33
34
35
36
37
38
39
40
41
42
43
44
45
//main
for(int i=0;i<n;i++){
if(owner(r[i]) != owner(r[i-1])){
//por si quiere mostrat $ o #
ans=max(ans,h[i-1]);
// ans subcadena maxima
}
}
//end main
/////////////////////// subcadenas distintas ///////////////
int dev=s.size()*(s.size()+1)/2;
s += $;
suff_arr();lcp();
for(int i=0;i<n;i++)dev-=h[i];
/////////////////////// FIN SUFFIX ARRAY
///////////////
72
Captulo 9
Geometria Computacional
9.1.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
#define MAXC 2501
struct Rect{
int x1,y1, x2,y2;
int color;
int area;
Rect(int _x1, int _y1, int _x2, int _y2){
x1 = _x1;
y1 = _y1;
x2 = _x2;
y2 = _y2;
getArea();
}
int getArea(){
if(x1>=x2 || y1>=y2)return area = 0;
return area = (x2-x1)*(y2-y1);
}
};
Rect interseccion(Rect t, Rect r){
int x1,y1,x2,y2;
x1 = max(t.x1,r.x1);
y1 = max(t.y1,r.y1);
x2 = min(t.x2,r.x2);
y2 = min(t.y2,r.y2);
Rect res(x1,y1,x2,y2);
return res;
}
9.2.
1
2
3
Interseccin de rectangulos
struct point{
double x,y;
};
73
9.3.
1
2
3
4
5
6
7
74
double distance_point_to_line(const point &a, const point &b, const point &pnt){
double u = ((pnt.x - a.x)*(b.x - a.x) + (pnt.y - a.y)*(b.y - a.y)) / distsqr
(a, b);
point intersection;
intersection.x = a.x + u*(b.x - a.x);
intersection.y = a.y + u*(b.y - a.y);
return dist(pnt, intersection);
}
Captulo 10
Utilitarios
10.1.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Plantilla
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
<algorithm>
<iostream>
<iterator>
<cassert>
<sstream>
<fstream>
<cstdlib>
<cstring>
<utility>
<complex>
<string>
<cctype>
<cstdio>
<vector>
<bitset>
<stack>
<queue>
<cmath>
<deque>
<list>
<set>
<map>
ll long long
lld long long int
sc scanf
pf printf
pi 2*acos(0.0)
f first
s second
sz size()
mp make_pair
r(input) freopen("2966.in","r",stdin)
w(output) freopen("output.txt","w",stdout)
maxall(v) *max_element(v.begin(),v.end())
minall(v) *min_element(v.begin(),v.end())
Sort(v) sort(v.begin(),v.end())
un(v) Sort(v), v.erase(unique(v.begin(),v.end()),v.end())
clr(a) memset(a,0,sizeof(a))
pb push_back
lim 100000
75
10.2.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Lectura rapida
#include <cstdio>
using namespace std;
char line[400000];//OJO maximo mas 3 para el \n y el \0
int now = 0;
inline int getInt(){
int n;
while(1)
if(line[now]!=0){
if(line[now]<0 || line[now]>9){
now++;
continue;
}
n = 0;
while(line[now]>=0 && line[now]<=9) {
n = n*10 + line[now] - 0;
now++;
}
return n;
}
else{
gets(line);
now = 0;
}
return n;
}
10.3.
Especificador
%c
%s
%d, %i
%u
%ld
%lu
%lld
%llu
%e, %f, %g
%lf
%o
%x
%patron
10.4.
Tipo
char
cadena
int
unsigned int
long int
unsigned long int
long long int
unsigned long long int
float
double
nmero octal
nmero hexadecimal
patron
C++ :
1
2
__builtin_popcount(unsigned int)
__builtin_popcountll(unsigned long long)
76
77
Java :
1
Integer.bitCount(int)
10.5.
Busqueda binaria
C++s Standard Template Library has four functions for binary search, depending on what information you want to
get. They all need
#include <algorithm>
The lower_bound() function returns an iterator to the first position where a value could be inserted without violating the
order; i.e. the first element equal to the element you want, or the place where it would be inserted.
int *ptr = std::lower_bound(array, array+len, what);
// a custom comparator can be given as fourth arg
The upper_bound() function returns an iterator to the last position where a value could be inserted without violating the
order; i.e. one past the last element equal to the element you want, or the place where it would be inserted.
int *ptr = std::upper_bound(array, array+len, what);
// a custom comparator can be given as fourth arg
The equal_range() function returns a pair of the results of lower_bound() and upper_bound().