You are on page 1of 25

Universidad Rey Juan Carlos – RaspuTeam

SWERC 2017 Universidad Rey Juan Carlos - RaspuTeam Mix


Matemáticas y Combinatoria 1. Longest Increasing Subsequence (C++)
1. Algoritmo de Euclides (MCM,LCM) (C++) 2. Knuth-Morris-Pratt (C++)
2. Min-cost max-flow (C++) 3. Búsqueda binaria y lineal (C++)
3. Push-relabel-max-flow (C++) 4. QuickSort (C++)
4. Min-cost bipartite matching (C++) 5. Latitud/longitud (C++)
5. Max bipartite matching (C++) 6. Números primos (C++)
6. Módulos, Teorema Chino del Resto, linear Diophantine) (C++) 7. Otras constantes (C++)
7. Sistemas de ecuaciones lineales, matriz inversa,determinantes 8. Ficheros leer (C++)
8. Simplex algorithm (C++) 9. Maximum submatrix (C++)
9. Números Catalanes (C++) 10. Partitions Integer (C++)
10. Números Eulerianos (C++) 11. Longest common Subsequence (C++)
11. Karatsuba (C++) 12. Longest increasing common Subsequence (C++)
12. Binomial Coeficiente, Combinaciones (C++) 13. Partitions of sets , Bell Numbers (C++)
13. Integracion por Simpson (C++) 14. FastInput (C++)
14. Modulo en Factorial (C++)
15. Fubinni Numbers (C++)
Grafos Algoritmo de Euclides (MCM,LCM) (C++)
1. Dijkstra's (C++) #include <iostream>
2. Kruskal's (C++) using namespace std;
3. DFS (Ciclos, Componentes Conexas) y BFS (C++) int gcd(int a, int b) {
while (b > 0) {
4. Eulerian path (C++)
int temp = b; b = a % b; a = temp; }
5. Strongly connected components (C++) return a; }
6. Floyd Warshall(C++) int lcm(int a, int b){ return a*(b/gcd(a,b));}
7. BellMan Ford (C++) int main() { int numero;
8. Prim (C++) while(1) {
9. Topological Sort (C++) cin>>numero; if(numero!=0) {
10. Puntos de Articulacion (C++) int array[numero];
Estructura de Datos for(int p=0; p<numero;p++) cin>>array[p];
int final=array[0];
1. Priority Queue (C++) for(int i=1;i<numero;i++)
2. Lazy Segment Tree (C++) final=lcm(final,array[i]);
3. Last Common ancestor (C++) cout<<final<<"\n"; }
4. Trie (C++) else break; } return 0; }
5. Next Permutations (C++)
6. Hojas de un árbol balanceado (C++)
7. Sets (C++)

1
Universidad Rey Juan Carlos – RaspuTeam
Min Cost Max Flow (C++) fill(found.begin(), found.end(), false);
fill(dist.begin(), dist.end(), INF);
// IN- graph, constructed using AddEdge(),source, sink fill(width.begin(), width.end(), 0);
// OUTPUT:(maximum flow value, minimum cost value), to dist[s] = 0; width[s] = INF;
obtain the actual Flow, look at positive values only. while (s != -1) { int best = -1;
found[s] = true;
for (int k = 0; k < N; k++) {
if (found[k]) continue;
Relax(s, k, cap[s][k] - flow[s][k], cost[s][k], 1);
Relax(s, k, flow[k][s], -cost[k][s], -1);
if (best == -1 || dist[k] < dist[best]) best = k; }
s = best; }
for (int k = 0; k < N; k++)
pi[k] = min(pi[k] + dist[k], INF);
return width[t]; }
#include <bits/stdc++.h> pair<L, L> GetMaxFlow(int s, int t) {
using namespace std; L totflow = 0, totcost = 0;
typedef vector<int> VI; while (L amt = Dijkstra(s, t)) { totflow += amt;
typedef vector<VI> VVI; for (int x = t; x != s; x = dad[x].first) {
typedef long long L; if (dad[x].second == 1) {
typedef vector<L> VL; flow[dad[x].first][x] += amt;
typedef vector<VL> VVL; totcost += amt * cost[dad[x].first][x];
typedef pair<int, int> PII; } else { flow[x][dad[x].first] -= amt;
typedef vector<PII> VPII; totcost -= amt * cost[x][dad[x].first]; } } }
const L INF = 0x3F3F3F3F; return make_pair(totflow, totcost); } };
struct MinCostMaxFlow { int N; int main() { int N, M;
VVL cap, flow, cost; VI found; while (scanf("%d%d", &N, &M) == 2) {
VL dist, pi, width; VPII dad; VVL v(M, VL(3));
MinCostMaxFlow(int N) : for (int i = 0; i < M; i++)
N(N), cap(N, VL(N)), flow(N, VL(N)), cost(N, VL(N)), scanf("%Ld%Ld%Ld", &v[i][0], &v[i][1], &v[i][2]);
found(N), dist(N), pi(N), width(N), dad(N) {} L D, K; scanf("%Ld%Ld", &D, &K);
void AddEdge(int from, int to, L cap, L cost) { MinCostMaxFlow mcmf(N+1);
this->cap[from][to] = cap; for (int i = 0; i < M; i++) {
this->cost[from][to] = cost;} mcmf.AddEdge(int(v[i][0]),int(v[i][1]),K,v[i][2]);
void Relax(int s, int k, L cap, L cost, int dir) { mcmf.AddEdge(int(v[i][1]),int(v[i][0]),K,v[i][2]);}
L val = dist[s] + pi[s] - pi[k] + cost; mcmf.AddEdge(0, 1, D, 0);
if (cap && val < dist[k]) { pair<L, L> res = mcmf.GetMaxFlow(0, N);
dist[k] = val; if (res.first == D) { printf("%Ld\n", res.second);
dad[k] = make_pair(s, dir); } else { printf("Impossible.\n"); } }
width[k] = min(cap, width[s]);}} return 0; }
L Dijkstra(int s, int t) {

2
Universidad Rey Juan Carlos – RaspuTeam
Push Relabel Max Flow (C++) void Gap(int k) {
for (int v = 0; v < N; v++) {
Given a graph undirected, weighted, compute max if (dist[v] < k) continue;
Flow/min cut from 1 to N. It solves random problems count[dist[v]]--;
with 10000 vertices and 1000000 edges in a few seconds, dist[v] = max(dist[v], N+1); count[dist[v]]++;
though it is possible to construct test cases that Enqueue(v); } }
achieve the worst-case. 4 6 | 1 2 3 | 2 3 4 | 3 1 2 | 2 void Relabel(int v) {
2 5 | 3 4 3 | 4 3 3 -> 5 count[dist[v]]--; dist[v] = 2*N;
// IN: graph, constructed using AddEdge() source sink for (int i = 0; i < G[v].size(); i++)
// OUTPUT: maximum flow value, To obtain the actual if (G[v][i].cap - G[v][i].flow > 0)
flow values, look at all edges with capacity > 0 (zero dist[v] = min(dist[v], dist[G[v][i].to] + 1);
capacity edges are residual edges). count[dist[v]]++; Enqueue(v); }
#include <bits/stdc++.h> void Discharge(int v) {
using namespace std; for (int i = 0; excess[v]>0&&i<G[v].size();i++)
typedef long long LL; Push(G[v][i]);
struct Edge { if (excess[v] > 0) {
int from, to, cap, flow, index; if (count[dist[v]] == 1) Gap(dist[v]);
Edge(int from, int to, int cap, int flow, int index) : else Relabel(v);} }
from(from), to(to), cap(cap), flow(flow), index(index) LL GetMaxFlow(int s, int t) {
{} }; count[0] = N-1; count[N] = 1; dist[s] = N;
struct PushRelabel { int N; active[s] = active[t] = true;
vector<vector<Edge> > G; vector<LL> excess; for (int i = 0; i < G[s].size(); i++) {
vector<int> dist, active, count; queue<int> Q; excess[s] += G[s][i].cap;
PushRelabel(int N) : N(N), G(N), excess(N), dist(N), Push(G[s][i]); }
active(N), count(2*N) {} while (!Q.empty()) {
void AddEdge(int from, int to, int cap) { int v = Q.front();
G[from].push_back(Edge(from, to, cap, 0, Q.pop(); active[v] = false;
G[to].size())); Discharge(v); }
if (from == to) G[from].back().index++; LL totflow = 0;
G[to].push_back(Edge(to, from, 0, 0, G[from].size() - for (int i = 0; i < G[s].size(); i++) totflow +=
1)); } G[s][i].flow; return totflow; } };
void Enqueue(int v) { // SPOJ problem #4110: Fast Maximum Flow
if (!active[v] && excess[v] > 0) { active[v] = true; int main() { int n, m;
Q.push(v); } } scanf("%d%d", &n, &m); PushRelabel pr(n);
void Push(Edge &e) { for (int i = 0; i < m; i++) {
int amt = int(min(excess[e.from], LL(e.cap - e.flow))); int a, b, c; scanf("%d%d%d", &a, &b, &c);
if (dist[e.from] <= dist[e.to] || amt == 0) return; if (a == b) continue;
e.flow += amt; pr.AddEdge(a-1, b-1, c); pr.AddEdge(b-1, a-1, c);}
G[e.to][e.index].flow -= amt;
excess[e.to] += amt; excess[e.from] -= amt; printf("%Ld\n", pr.GetMaxFlow(0, n-1)); return 0;}
Enqueue(e.to); }

3
Universidad Rey Juan Carlos – RaspuTeam
Min Cost Bipartite Matching (C++) fill(seen.begin(), seen.end(), 0);
for (int k = 0; k < n; k++)
// Algorithm for finding min cost perfect matchings in dist[k] = cost[s][k] - u[s] - v[k];
dense graphs. In practice, it solves 1000x1000 problems int j = 0;
in around 1 second. cost[i][j] = cost for pairing left while (true) { j = -1;
node i with right node j. Lmate[i] = index of right for (int k = 0; k < n; k++) {
node that left node i pairs with. Rmate[j] = index of if (seen[k]) continue;
left node that right node j pairs with if (j == -1 || dist[k] < dist[j]) j = k; }
// The values in cost[i][j] may be positive or seen[j] = 1;
negative. To perform if (Rmate[j] == -1) break;
// maximization, simply negate the cost[][] matrix. const int i = Rmate[j];
// Find a minimum cost matching between S and T among for (int k = 0; k < n; k++) {
all those with maximum cardinality. if (seen[k]) continue;
#include <bits/stdc++.h> const double new_dist = dist[j] +
using namespace std; cost[i][k] - u[i] - v[k];
typedef vector<double> VD; if (dist[k] > new_dist) {
typedef vector<VD> VVD; dist[k] = new_dist;
typedef vector<int> VI; dad[k] = j; } } }
double MinCostMatching(const VVD &cost, VI &Lmate, VI for (int k = 0; k < n; k++) {
&Rmate) { if (k == j || !seen[k]) continue;
int n = int(cost.size()); const int i = Rmate[k];
VD u(n); VD v(n); v[k] += dist[k] - dist[j];
for (int i = 0; i < n; i++) {u[i] = cost[i][0]; u[i] -= dist[k] - dist[j]; }
for (int j = 1; j < n; j++) u[i] = min(u[i], u[s] += dist[j];
cost[i][j]); } // augment along path
for (int j = 0; j < n; j++) { while (dad[j] >= 0) {
v[j] = cost[0][j] - u[0]; const int d = dad[j];
for (int i = 1; i < n; i++) v[j] = min(v[j], cost[i][j] Rmate[j] = Rmate[d]; Lmate[Rmate[j]] = j;
- u[i]); } j = d; }
Lmate = VI(n, -1); Rmate = VI(n, -1); Rmate[j] = s; Lmate[s] = j; mated++; }
int mated = 0; double value = 0;
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) { value += cost[i][Lmate[i]];
if (Rmate[j] != -1) continue; return value;
if (fabs(cost[i][j] - u[i] - v[j]) < 1e-10) {
Lmate[i] = j; Rmate[j] = i; mated++; }
break; } } }
VD dist(n); VI dad(n); VI seen(n);
while (mated < n) { int s = 0;
while (Lmate[s] != -1) s++;
fill(dad.begin(), dad.end(), -1);

4
Universidad Rey Juan Carlos – RaspuTeam
Max bipartite Matching (C++) return a; }
int lcm(int a, int b) {
//IN: w[i][j]=edge between row node i and column node j return a / gcd(a, b)*b; }
//OP: mr[i]=assignment for row node i, -1 if unassigned // (aˆb) mod m via successive squaring
//mc[j] = assignment for column node j, -1 if int powermod(int a, int b, int m) {
unassigned function returns number of matches made int ret = 1;
#include <vector> while (b) {
using namespace std; if (b & 1) ret = mod(ret*a, m);
typedef vector<int> VI; a = mod(a*a, m); b >>= 1; }
typedef vector<VI> VVI; return ret; }
bool FindMatch(int i, const VVI &w, VI &mr, VI &mc, VI int extended_euclid(int a,int b,int &x,int &y) {
&seen) { int xx = y = 0; int yy = x = 1;
for (int j = 0; j < w[i].size(); j++) { while (b) { int q = a / b;
if (w[i][j] && !seen[j]) { int t = b; b = a%b; a = t;
seen[j] = true; t = xx; xx = x - q*xx; x = t;
if (mc[j] < 0 || FindMatch(mc[j], w, mr, mc, seen)) { t = yy; yy = y - q*yy; y = t; } return a; }
mr[i] = j; mc[j] = i; // finds all solutions to ax = b (mod n)
return true; } } } VI modular_linear_equation_solver
return false; } (int a, int b, int n) {
int BipartiteMatching(const VVI &w, VI &mr, VI &mc) { int x, y; VI ret;
mr = VI(w.size(), -1); int g = extended_euclid(a, n, x, y);
mc = VI(w[0].size(), -1); if (!(b%g)) {
int ct = 0; x = mod(x*(b / g), n);
for (int i = 0; i < w.size(); i++) { for (int i = 0; i < g; i++)
VI seen(w[0].size()); ret.push_back(mod(x + i*(n / g), n));
if (FindMatch(i, w, mr, mc, seen)) ct++; } } return ret; }
return ct; } int mod_inverse(int a, int n) {
int x, y;
int g = extended_euclid(a, n, x, y);
Módulos, Teorema Chino del Resto, etc (C++) if (g > 1) return -1; return mod(x, n); }
PII chinese_remainder_theorem
(int m1, int r1, int m2, int r2){
#include <bits/stdc++.h> int s, t;
using namespace std; int g = extended_euclid(m1, m2, s, t);
typedef vector<int> VI; if (r1%g != r2%g) return make_pair(0, -1);
typedef pair<int, int> PII; return make_pair(mod(s*r2*m1 + t*r1*m2, m1*m2)
// return a % b (positive value) /g,m1*m2 / g); }
int mod(int a, int b) { PII chinese_remainder_theorem
return ((a%b) + b) % b; } (const VI &m, const VI &r) {
int gcd(int a, int b) { PII ret = make_pair(r[0], m[0]);
while (b) { int t = a%b; a = b; b = t; } for (int i = 1; i < m.size(); i++) {

5
Universidad Rey Juan Carlos – RaspuTeam
ret = chinese_remainder_theorem(ret.second, Sistemas de ecuaciones lineales, inversa, etc (C++)
ret.first, m[i], r[i]);
if (ret.second == -1) break; } // Gauss-Jordan elimination with full pivoting.
return ret; } // (1) solving systems of linear equations (AX=B)
// computes x and y such that ax + by = c // (2) inverting matrices (AX=I)
// returns whether the solution exists // (3) computing determinants of square matrices
bool linear_diophantine(int a, int b, int c, int &x, // INPUT: a[][] = an nxn matrix
int &y) { // b[][] = an nxm matrix
if (!a && !b) { // OUTPUT: X = an nxm matrix (stored in b[][])
if (c) return false; x = 0; y = 0; return true; } // Aˆ{-1} = an nxn matrix (stored in a[][])
if (!a) { if (c % b) return false; // returns determinant of a[][]
x = 0; y = c / b; return true;} #include <bits/stdc++.h>
if (!b) { if (c % a) return false; using namespace std;
x = c / a; y = 0; return true; } const double EPS = 1e-10;
int g = gcd(a, b); typedef vector<int> VI; typedef double T;
if (c % g) return false; typedef vector<T> VT;
x = c / g * mod_inverse(a / g, b / g); typedef vector<VT> VVT;
y = (c - a*x) / b; return true; } T GaussJordan(VVT &a, VVT &b) {
int main() { const int n = a.size(); const int m = b[0].size();
cout << gcd(14, 30) << endl; VI irow(n), icol(n), ipiv(n); T det = 1;
// expected: 2 -2 1 int x, y; for (int i = 0; i < n; i++) {
int g = extended_euclid(14, 30, x, y); int pj = -1, pk = -1;
cout << g << " " << x << " " << y << endl; for (int j = 0; j < n; j++) if (!ipiv[j])
// expected: 95 451 for (int k = 0; k < n; k++) if (!ipiv[k])
VI sols = modular_linear_equation_solver(14, 30, 100); if (pj == -1 || fabs(a[j][k]) > fabs(a[pj][pk])) {
for (int i = 0; i < sols.size(); i++) cout << sols[i] pj = j; pk = k; }
<< " "; if (fabs(a[pj][pk]) < EPS) {
cout << endl; cerr << "Matrix is singular." << endl; exit(0); }
// expected: 8 ipiv[pk]++; swap(a[pj], a[pk]); swap(b[pj], b[pk]);
cout << mod_inverse(8, 9) << endl; if (pj != pk) det *= -1; irow[i] = pj; icol[i] = pk;
// expected: 23 105 T c = 1.0 / a[pk][pk];
// 11 12 det *= a[pk][pk]; a[pk][pk] = 1.0;
PII ret = chinese_remainder_theorem(VI({ 3, 5, 7 }), for (int p = 0; p < n; p++) a[pk][p] *= c;
VI({ 2, 3, 2 })); for (int p = 0; p < m; p++) b[pk][p] *= c;
cout << ret.first << " " << ret.second << endl; for (int p = 0; p < n; p++) if (p != pk) {
ret = chinese_remainder_theorem(VI({4,6}), VI({3,5 })); c = a[p][pk]; a[p][pk] = 0;
cout << ret.first << " " << ret.second << endl;// 5 -15 for (int q=0; q<n; q++) a[p][q]-=a[pk][q]*c;
if (!linear_diophantine(7,2,5, x, y)) cout << "ERROR\n" for (int q=0; q<m; q++) b[p][q]-=b[pk][q]*c; } }
cout << x << " " << y << endl; for (int p = n-1; p>=0; p--) if (irow[p]!=icol[p]){
for (int k = 0; k < n; k++) swap(a[k][irow[p]],
return 0; } a[k][icol[p]]); } return det; }

6
Universidad Rey Juan Carlos – RaspuTeam
int main() { typedef long double DOUBLE;
const int n = 4; const int m = 2; typedef vector<DOUBLE> VD;
double A[n][n] = { typedef vector<VD> VVD;
{1,2,3,4},{1,0,1,0},{5,3,2,4},{6,1,4,6} }; typedef vector<int> VI;
double B[n][m] = { {1,2},{4,3},{5,6},{8,7} }; const DOUBLE EPS = 1e-9;
VVT a(n), b(n); struct LPSolver {
for (int i = 0; i < n; i++) { int m, n; VI B, N; VVD D;
a[i] = VT(A[i], A[i] + n); LPSolver(const VVD &A, const VD &b, const VD &c) :
b[i] = VT(B[i], B[i] + m); } m(b.size()), n(c.size()), N(n + 1),
double det = GaussJordan(a, b); // expected: 60 B(m), D(m + 2, VD(n + 2)) {
cout << "Determinant: " << det << endl; for (int i = 0; i < m; i++)
// expected: -0.233333 0.166667 0.133333 0.0666667 for (int j = 0; j < n; j++) D[i][j] = A[i][j];
// 0.166667 0.166667 0.333333 -0.333333 for (int i = 0; i < m; i++) {
// 0.233333 0.833333 -0.133333 -0.0666667 B[i] = n + i; D[i][n] = -1; D[i][n + 1] = b[i]; }
// 0.05 -0.75 -0.1 0.2 for (int j = 0; j < n; j++) {
cout << "Inverse: " << endl; N[j] = j; D[m][j]=-c[j]; }N[n]=-1; D[m+1][n]=1;}
for (int i = 0; i < n; i++) { void Pivot(int r, int s) {
for (int j = 0; j < n; j++) double inv = 1.0 / D[r][s];
cout << a[i][j] << ' '; cout << endl; } for (int i = 0; i < m + 2; i++) if (i != r)
// expected: 1.63333 1.3 for (int j = 0; j < n + 2; j++) if (j != s)
// -0.166667 0.5 // 2.36667 1.7 // -1.85 -1.35 D[i][j] -= D[r][j] * D[i][s] * inv;
cout << "Solution: " << endl; for (int j = 0; j < n + 2; j++)
for (int i = 0; i < n; i++) { if (j!=s) D[r][j]*=inv;
for (int j = 0; j < m; j++) for (int i = 0; i < m + 2; i++)
cout << b[i][j] << ' '; cout << endl; }} if (i!=r) D[i][s]*=-inv; D[r][s] = inv;
swap(B[r], N[s]); }
bool Simplex(int phase) {
Simplex Algorithm (C++) int x = phase == 1 ? m + 1 : m; while (true) {
// Two-phase simplex algorithm for solving linear int s = -1; for (int j = 0; j <= n; j++) {
programs of the form if (phase == 2 && N[j] == -1) continue;
// maximize cˆT x if (s == -1 || D[x][j] < D[x][s]||D[x][j]==D[x][s]
// subject to Ax <= b x >= 0 && N[j] < N[s]) s = j; }
// INPUT: A -- an m x n matrix if (D[x][s] > -EPS) return true; int r = -1;
// b -- an m-dimensional vector for (int i = 0; i < m; i++) {
// c -- an n-dimensional vector if (D[i][s] < EPS) continue;
// x -- a vector where the optimal solution will be if (r == -1 || D[i][n + 1] / D[i][s] <
stored D[r][n + 1] / D[r][s] ||
// OUTPUT: value of the optimal solution (D[i][n+1]/D[i][s])==(D[r][n+1]/D[r][s])
// arguments. Then, call Solve(x). && B[i] < B[r]) r = i; }
#include <bits/stdc++.h> if (r == -1) return false;
using namespace std; Pivot(r, s); } }

7
Universidad Rey Juan Carlos – RaspuTeam
DOUBLE Solve(VD &x) { int r = 0; Números Catalanes (C++)
for (int i = 1; i < m; i++) if (D[i][n + 1] < D[r][n +
1]) r = i; // 1 1 2 5 14 42 132 429 1430 4862 16796 58786
if (D[r][n + 1] < -EPS) { Pivot(r, n); #include<iostream>
if (!Simplex(1) || D[m + 1][n + 1] < -EPS) return - using namespace std;
numeric_limits<DOUBLE>::infinity(); unsigned long int catalanDP(unsigned int n){
for (int i = 0; i < m; i++) if (B[i] == -1) { unsigned long int catalan[n+1];
int s = -1; catalan[0] = catalan[1] = 1;
for (int j = 0; j <= n; j++) for (int i=2; i<=n; i++){
if (s == -1 || D[i][j] < D[i][s] || D[i][j] == D[i][s] catalan[i] = 0;
&& N[j] < N[s]) s = j; for (int j=0; j<i; j++)
Pivot(i, s); } } catalan[i]+=catalan[j]*catalan[i-j-1];
if (!Simplex(2)) return } return catalan[n]; }
numeric_limits<DOUBLE>::infinity(); x = VD(n); int main() {
for (int i = 0; i < m; i++) if (B[i] < n) x[B[i]] = for (int i = 0; i < 10; i++)
D[i][n + 1]; cout << catalanDP(i) << " "; return 0; }
return D[m][n + 1]; } };
int main() { const int m = 4; const int n = 3;
DOUBLE _A[m][n] = { Números Eulerianos (C++)
{ 6,-1,0}, {-1,-5,0}, {1,5,1}, {-1,-5,-1}}; // C++ program to print all increasing sequences of
DOUBLE _b[m] = { 10, -4, 5, -5 }; // length 'k' such that the elements in every
DOUBLE _c[n] = { 1, -1, 0 }; sequence are from first 'n' natural numbers.
VVD A(m); VD b(_b, _b + m); VD c(_c, _c + n); // Input: k = 2, n = 3 Output: 1 2 | 1 3 | 2 3
for (int i = 0; i < m; i++) A[i] = VD(_A[i], _A[i] + #include<iostream>
n); using namespace std;
LPSolver solver(A, b, c); VD x; void printSeqUtil(int n, int k, int &len, int
DOUBLE value = solver.Solve(x); arr[]){
cerr << "VALUE: " << value << endl; // VALUE: 1.29032 if (len == k) {
cerr << "SOLUTION:"; // SOLUTION: 1.74194 0.451613 1 printArr(arr, k); return; }
for (size_t i = 0; i < x.size(); i++) cerr << " " << int i = (len == 0)? 1 : arr[len-1] + 1;
x[i]; cerr << endl; return 0; } len++;
while (i<=n) {
arr[len-1] = i;
printSeqUtil(n, k, len, arr);
i++; } len--; }
void printSeq(int n, int k) {
int arr[k]; int len = 0;
printSeqUtil(n, k, len, arr); }
int main() {
int k = 3, n = 7; printSeq(n, k); return 0; }

8
Universidad Rey Juan Carlos – RaspuTeam
Karatsuba (C++) long int P2 = multiply(Xr, Yr);
long int P3 = multiply(addBitStrings(Xl, Xr),
#include<bits/stdc++.h> addBitStrings(Yl, Yr));
using namespace std; return P1*(1<<(2*sh)) +
int makeEqualLength(string &str1, string &str2){ (P3 - P1 - P2)*(1<<sh) + P2; }
int len1 = str1.size(); // Driver program to test aboev functions - 120
int len2 = str2.size(); int main() {
if (len1 < len2){ printf ("%ld\n", multiply("1100", "1010")); }
for (int i = 0 ; i < len2 - len1 ; i++)
str1 = '0' + str1;
return len2;} Binomial Coeficiente (C++)
else if (len1 > len2) {
for (int i = 0 ; i < len1 - len2 ; i++) //n! mod p
str2 = '0' + str2; } #include <bits/stdc++.h>
return len1;} // If len1 >= len2 using namespace std;
string addBitStrings( string first, string second ){ // Utility function to do modular exponentiation.
string result; // To store the sum bits // It returns (x^y) % p
// make the lengths same before adding int power(int x, unsigned int y, int p)
int length = makeEqualLength(first, second); { int res = 1; // Initialize result
int carry = 0; // Initialize carry x = x % p; while (y > 0) {
for (int i = length-1 ; i >= 0 ; i--) { // If y is odd, multiply x with result
int firstBit = first.at(i) - '0'; if (y & 1)
int secondBit = second.at(i) - '0'; res = (res*x) % p;
int sum = (firstBit ^ secondBit ^ carry)+'0'; y = y>>1; // y = y/2
result = (char)sum + result; x = (x*x) % p; }
carry = (firstBit&secondBit) | return res; }
(secondBit&carry) | (firstBit&carry); } int modInverse(int a, int p) {
if (carry) result = '1' + result; return power(a, p-2, p); }
return result; } // Returns n! % p using Wilson's Theorem
int multiplyiSingleBit(string a, string b) int modFact(int n, int p) {
{ return (a[0] - '0')*(b[0] - '0'); } if (p <= n)
long int multiply(string X, string Y) { return 0; int res = (p-1);
int n = makeEqualLength(X, Y); for (int i=n+1; i<p; i++)
if (n == 0) return 0; res = (res * modInverse(i, p)) % p;
if (n == 1) return multiplyiSingleBit(X, Y); return res; }
int fh = n/2; int sh = (n-fh); int main() {
string Xl = X.substr(0, fh); int n = 25, p = 29;
string Xr = X.substr(fh, sh); cout << modFact(n, p);
string Yl = Y.substr(0, fh); return 0; }
string Yr = Y.substr(fh, sh);
long int P1 = multiply(Xl, Yl);

9
Universidad Rey Juan Carlos – RaspuTeam
Integración por Simpson (C++) // n! % p is 0 if n >= p
if (p <= n) return 0;
int res = (p-1);
for (int i=n+1; i<p; i++)
res = (res * modInverse(i, p)) % p;
return res; }
#include <bits/stdc++.h> int main() {
double Simpson(double a, double b, int k, double int n = 25, p = 29;
(*f)(double)){ cout << modFact(n, p);
double dx, x, t=0; int i; return 0; }
dx = (b-a)/(2.0*k);
for( i=0; i<k; i++ ) {
t += (i==0 ? 1.0 : 2.0) * (*f)(a+2.0*i*dx); Fubini Numbers (C++)
t += 4.0 * (*f)(a+(2.0*i+1.0)*dx);}
t += (*f)(b); //0, 1, 1, 3, 13, 75, 541, 4683, 47293, 545835
return t * (b-a)/6.0/k; } #include<bits/stdc++.h>
double example_function(double x) { using namespace std;
return x*x; } #define LL long long #define nmax 3100
int main(void){ #define nnum 46337
int k; double a = 0, b=5.0; LL num[nmax][nmax], fac[nmax];
printf("Integral from %f to %f is:\n",a,b); void init() { int i, j;
for( k=1; k<=40; k++ ) { for (i = 1, fac[0] = 1; i < nmax; i++) {
printf(" k = %3d: fac[i] = fac[i - 1] * i % nnum; }
%f\n",k,Simpson(a,b,k,example_function)); } for (i = 1; i < nmax; i++) {
num[i][1] = 1; num[i][0] = 0; }
return 0; } for (i = 2; i < nmax; i++) {
for (j = 1; j < nmax; j++) {
if (i == j) {
Módulo en factorial (C++)
num[i][i] = 1;
// n! % p using Wilson's Theorem } else {
#include <bits/stdc++.h> num[i][j] = (num[i - 1][j - 1] + num[i - 1]
using namespace std; [j] * j) % nnum; } } } }
int power(int x, unsigned int y, int p) { int main() { ofstream myfile;
int res = 1; x = x % p; myfile.open ("example.txt");
while (y > 0) { init(); int N=0, i; LL res;
if (y & 1) res = (res*x) % p; while (N!=3050) {
y = y>>1; x = (x*x) % p; } for (i = 1, res = 0; i <= N; i++) {
return res;} res += num[N][i] * fac[i]; res %= nnum;}
Assumption: p is prime myfile<<res<<","; printf("%I64d\n", res);
int modInverse(int a, int p) { N++; } myfile.close(); return 0; }
return power(a, p-2, p); }
int modFact(int n, int p) {

10
Universidad Rey Juan Carlos – RaspuTeam
Dijkstra (C++) int from, to, weight; scanf("%d %d %d",&from,
&to, &weight);
Pesos no negativos graph[from].push_back(edge(from,to,weight));
#include <bits/stdc++.h> graph[to].push_back(edge(to, from, weight));
using namespace std; // borrar linea si es dirigido}
const int MAXN = 100100; printf("Dijkstra d%d a %d es %d\n",a,b,
const int INF = 0x3f3f3f3f; dijkstra(a,b));
struct edge{ return 0; }}
int from, to, weight;
edge(){}
edge(int a, int b, int c){ Kruskal (C++)
from = a; to = b; weight = c; }};
struct state{ // El algoritmo de Kruskal calcula el tamaño
int node, dist; state(){} minimo de un bosque es decir union de arboles
state(int a, int b){ cada uno conectado a una componente, posibilitando
node = a; dist = b; } una matriz de adyacencia dada una matriz con peso
bool operator<(const state &other)const{ en los nodos donde -1 es si no existe el vertice.
return other.dist < other.dist; } }; Devuelve el minimo peso del bosque calculando los
vector<edge> graph[MAXN]; vertices guardados en T, usa un arbol disjunto para
int dist[MAXN]; int a=1, b=3; int N,E; amortizar la efectividad en un tiempo contante
int dijkstra(int start, int end){ siendo la complejidad O(E*log(E))
dist[start] = 0; #include <bits/stdc++.h>
priority_queue<state> pq; using namespace std;
pq.push(state(start, 0)); const int MAXN = 100100;
while(!pq.empty()){ const int INF = 0x3f3f3f3f;
state cur = pq.top(); pq.pop(); struct edge{
if(dist[cur.node] < cur.dist) continue; int from, to, weight; edge(){}
if(cur.node == end) return cur.dist; edge(int a, int b, int c){
for(int i=0;i<graph[cur.node].size();i++){ from = a; to = b; weight = c;}
int dest = graph[cur.node][i].to; bool operator<(const edge &other)const{
int wht = graph[cur.node][i].weight + cur.dist; return weight < other.weight;} };
if(dist[dest] <= wht) continue; struct UF{
dist[dest] = wht; int parents[MAXN]; int sz[MAXN];
pq.push(state(dest, wht)); int components; int mst_sum;
} } return -1; } UF(int n){
int main(){ for(int i=0;i<n;i++){
freopen("dijkstra.in","r",stdin); parents[i] = i; sz[i] = 1; }
scanf("%d %d",&N,&E); components = n; mst_sum = 0; }
memset(dist,0x3f,sizeof(dist)); int find(int n){
for(int i=1;i<=N;i++) graph[i].clear(); return n==parents[n] ? n : find(parents[n]);
for(int i=0;i<E;i++){ }
bool isConnected(int a, int b){

11
Universidad Rey Juan Carlos – RaspuTeam
return find(a) == find(b); } best_result = min(
void connect(int a, int b, int weight){ best_result,
if(isConnected(a, b)) return; DFS(dest, target)+1 );}
int A,B; A = find(a); B = find(b); return best_result; }
if(sz[A] > sz[B]){ int BFS(int start, int target){
parents[B] = A; sz[A] += sz[B]; } queue<pair<int,int> > q;
else{ parents[A] = B; sz[B] += sz[A]; q.push(make_pair(start,0));
} mst_sum += weight; components--; } }; visited[start] = true;
int a=1; int N,E; while(!q.empty()){
int main(){ pair<int,int> current = q.front(); q.pop();
freopen("mst.in","r",stdin); if(current.first == target) return
scanf("%d %d",&N,&E); current.second;
vector<edge> edges; for(int i=0;i<graph[current.first].size();i++){
UF uf = UF(N); int dest = graph[current.first][i];
for(int i=0;i<E;i++){ if(visited[dest]) continue;
int from, to, weight; scanf("%d %d %d",&from, &to, visited[dest] = true;
&weight); q.push(make_pair(dest,current.second+1));
edges.push_back(edge(from,to,weight));} } }
sort(edges.begin(), edges.end()); return -1; }
for(int i=0;i<E;i++) uf.connect(edges[i].from,
edges[i].to, edges[i].weight); int main(){
printf("Kruskal de %d es %d\n",a,uf.mst_sum); freopen("recorridos.in","r",stdin);
return 0; } scanf("%d %d",&N,&E);
for(int i=1;i<=N;i++) graph[i].clear();
for(int i=0;i<E;i++){
DFS (Componentes Conexas, Ciclos) y BFS (C++) int from, to; scanf("%d %d",&from, &to);
graph[from].push_back(to);
#include <bits/stdc++.h> graph[to].push_back(from);
using namespace std; // borrar linea si es dirigido }
const int MAXN = 100100; memset(visited,0,sizeof(visited));
const int INF = 0x3f3f3f3f; printf("BFS de %d a %d es %d\n",a,b,BFS(a,b));
vector<int> graph[MAXN]; memset(visited,0,sizeof(visited));
bool visited[MAXN]; printf("DFS de %d a %d es %d\n",a,b,DFS(a,b));
int a=1, b=6; int N,E; return 0; }
int DFS(int node, int target){
if(node == target) return 0;
if(visited[node]) return INF;
visited[node] = true;
int best_result = INF;
for(int i=0;i<graph[node].size();i++){
int dest = graph[node][i];

12
Universidad Rey Juan Carlos – RaspuTeam
// Contar ciclos void DFSUtil(int v, bool visited[]); };
bool DFS(int node, int parent){
if(visited[node]) return false; void Graph::addEdge(int v, int w) {
visited[node] = true; bool res = true; adj[v].push_back(w);
for(unsigned int i=0;i<graph[node].size();i++){ adj[w].push_back(v); }
int dest = graph[node][i]; void Graph::DFSUtil(int v, bool visited[]) {
if(dest==parent && visited[dest]) visited[v] = true;
return true; list<int>::iterator i;
if(visited[dest]) continue; for (i = adj[v].begin(); i != adj[v].end(); ++i)
res = DFS(dest,node); } if (!visited[*i])
return res; } DFSUtil(*i, visited); }
bool Graph::isConnected() {
// Componentes Conexas bool visited[V]; int i;
void DFS(int node){ for (i = 0; i < V; i++)
if(visited[node]) return; visited[i] = false;
visited[node] = true; for (i = 0; i < V; i++)
for(int i=0;i<graph[node].size();i++){ if (adj[i].size() != 0) break;
int dest = graph[node][i]; if (i == V) return true;
DFS(dest); } } DFSUtil(i, visited);
int main(){ for (i = 0; i < V; i++)
memset(visited,0,sizeof(visited)); if (visited[i] == false && adj[i].size() > 0)
int comps = 0; return false;
for(int i=1;i<=N;i++){ return true; }
if(!visited[i]){ DFS(i); comps++; } } // The function returns one of the following values
printf("Hay %d componentes\n", comps); // 0 --> If graph is not Eulerian
return 0; } // 1 --> If graph has an Euler path (Semi-Eulerian)
// 2 --> If graph has an Euler Circuit (Eulerian)
int Graph::isEulerian() {
Eulerian Path (C++) if (isConnected() == false) return 0;
#include<bits/stdc++.h> int odd = 0;
using namespace std; for (int i = 0; i < V; i++)
class Graph { if (adj[i].size() & 1)
int V; list<int> *adj; odd++;
public: if (odd > 2)
Graph(int V) {this->V = V; adj = new return 0;
list<int>[V]; } // If odd count is 2, then semi-eulerian.
~Graph() { delete [] adj; } // If odd count is 0, then eulerian
void addEdge(int v, int w); return (odd)? 1 : 2; }
int isEulerian(); void test(Graph &g) {
bool isConnected(); int res = g.isEulerian();

13
Universidad Rey Juan Carlos – RaspuTeam
if (res == 0) vector<int> orders;
cout << "graph is not Eulerian\n"; vector<int> Graph[MAX], reverseGraph[MAX];
else if (res == 1) void dfs1 (int node) {visited[0][node] = true;
cout << "graph has a Euler path\n"; componentID[0][node] = componentCount[0];
else for (int i : reverseGraph[node]) {
cout << "graph has a Euler cycle\n"; } if (!visited[0][i]) dfs1(i); }
int main() { orders.push_back(node); }
Graph g1(5); g1.addEdge(1, 0); g1.addEdge(0, 2); void dfs2 (int node) {
g1.addEdge(2, 1); g1.addEdge(0, 3); visited[1][node] = true;
g1.addEdge(3, 4); test(g1); componentID[1][node] = componentCount[1];
for (int i : Graph[node])
Graph g3(5); g3.addEdge(1, 0); g3.addEdge(0, 2); if (!visited[1][i]) dfs2(i); }
g3.addEdge(2, 1); g3.addEdge(0, 3); int main() { scanf("%d%d", &N, &M);
g3.addEdge(3, 4); g3.addEdge(1, 3); test(g3); for (int i = 0; i < M; i ++) {int u, v;
// connected in the form of cycle scanf("%d%d", &u, &v);
Graph g5(3); test(g5); Graph[u].push_back(v);
return 0; } reverseGraph[v].push_back(u); }
/* graph has a Euler path | graph is not Eulerian for (int i = 1; i <= N; i ++) {
graph has a Euler cycle */ if (!visited[0][i]) {
componentCount[0] ++; dfs1(i); } }
reverse(orders.begin(), orders.end());
Strongly Connected Components (C++) for (int i : orders) {
if (!visited[1][i]) {
componentCount[1] ++; dfs2(i); } }
for (int i = 1; i <= N; i ++)
for (int j : reverseGraph[i])
if (componentID[1][i] != componentID[1][j])
degree[componentID[1][j]] ++; int startings = 0;
for (int i = 1; i <= componentCount[1]; i ++)
if (!degree[i]) startings ++;
if (startings > 1) puts("0");
else { vector<int> output;
for (int i = 1; i <= N; i ++)
/* 4 4 | 1 2 | 3 2 | 4 3 | 2 1 if (!degree[componentID[1][i]])
Output: 2 | 1 2 */ output.push_back(i);
#include <bits/stdc++.h> printf("%d\n", (int)output.size());
using namespace std; for (int i = 0; i < (int)output.size(); i ++)
const int MAX = 100005; int N, M; { printf("%d", output[i]);
int componentCount[2]; if (i < (int)output.size() - 1) putchar(' ');
int componentID[2][MAX]; int degree[MAX]; } putchar('\n');} return 0;}
bool visited[2][MAX];

14
Universidad Rey Juan Carlos – RaspuTeam
Floyd Warshall (C++) bool visited[MAXN];
int a=1; int N,E;
#include<bits/stdc++.h> int prim(int start){
using namespace std; //No tiene porque ser simétrica! priority_queue<state> pq;
#define INF 0x3F3F3F3F pq.push(state(start, 0));
int dist[4][4] = { { 0, 5 ,INF,10}, int sum = 0;
{INF, 0 ,3 ,INF}, while(!pq.empty()){
{INF, INF,0 ,1}, state cur = pq.top(); pq.pop();
{INF, INF,INF,0}}; if(visited[cur.node]) continue;
void floydWarshall (); sum += cur.dist;
{ visited[cur.node] = true;
int dist[4][4], i, j, k; for(int i=0;i<graph[cur.node].size();i++){
for (i = 0; i < 4; i++) int dest = graph[cur.node][i].to;
for (j = 0; j < 4; j++) int wht = graph[cur.node][i].weight;
dist[i][j] = graph[i][j]; if(visited[dest]) continue;
for (k = 0; k < 4; k++) pq.push(state(dest, wht));
for (i = 0; i < 4; i++) } } return sum; }
for (j = 0; j < 4; j++) int main(){
dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);} freopen("mst.in","r",stdin);
int main(){ floydWarshall();return 0;} scanf("%d %d",&N,&E);
memset(visited,0,sizeof(visited));
for(int i=1;i<=N;i++) graph[i].clear();
Prim (C++) for(int i=0;i<E;i++){
#include <bits/stdc++.h> int from,to,weight; scanf("%d %d %d",&from,&to,
using namespace std; &weight);
const int MAXN = 100100; graph[from].push_back(edge(from,to,weight));
const int INF = 0x3f3f3f3f; graph[to].push_back(edge(to, from, weight));
struct edge{ // borrar linea si es dirigido }
int from, to, weight; printf("Prim de %d es %d\n",a,prim(a));
edge(){} return 0;}
edge(int a, int b, int c){
from = a; to = b; weight = c; } };
BellMan Ford (C++)
struct state{
int node, dist; #include<bits/stdc++.h>
state(){} #define N 2001
state(int a, int b){ #define MAX 100000000
node = a; dist = b; } using namespace std;
bool operator<(const state &other)const{ int a[N], b[N], t[N];
return other.dist < dist; } }; bool BellmanFord(int n, int m) {
int d[N];
vector<edge> graph[MAXN]; fill(d, d + n, MAX); d[0] = 0;

15
Universidad Rey Juan Carlos – RaspuTeam
//bellman ford scanf("%d %d",&N,&E);
for (int i = 0; i < n - 1; i++) for(int i=1;i<=N;i++) graph[i].clear();
for (int j = 0; j < m; j++) for(int i=0;i<E;i++){
if (d[a[j]] != MAX) int from, to; scanf("%d %d",&from, &to);
if (d[a[j]] + t[j] < d[b[j]]) graph[from].push_back(to); }
d[b[j]] = d[a[j]] + t[j]; printf("Ordenamiento topologico:");
//negative cycle check //Asumo que el nodo 1 no es dependiente de nadie
for (int j = 0; j < m; j++) DFS(1);
if (d[a[j]] + t[j] < d[b[j]]) while(!topological_order.empty()){
return true; return false; } printf(" %d",topological_order.top());
int main() { topological_order.pop(); }
int Case, n, m; printf("\n"); return 0; }
scanf("%d", &Case);
while (Case--) { int i; scanf("%d%d", &n, &m);
for (i = 0; i < m; i++) Puntos de articulación (C++)
scanf("%d%d%d", &a[i], &b[i], &t[i]); #include <bits/stdc++.h>
puts(BellmanFord(n, m) ? "possible" : "not #define oo 1000
possible"); } return 0; } int link[100][100], n;
//Sample Input 2 - 3 3 | 0 1 1000 | 1 2 15 | 2 1 -42 | int depth[100], low[100];
4 4 |0 1 10 |1 2 20 |2 3 30 |3 0 -60 Sample Output int used[100], cut;
posible | not possible int DFS(int node, int d, int parent) {
int i, back = oo, son = 0, tmp, flag = 0;
depth[node] = d;
Topological Sort (C++)
for(i = 1; i <= n; i++) {
if(link[node][i] == 1) {
#include <bits/stdc++.h> if(used[i] == 0) {
using namespace std; used[i] = 1;
const int MAXN = 100100; tmp = DFS(i, d+1, node);
const int INF = 0x3f3f3f3f; if(tmp >= d) flag = 1;
vector<int> graph[MAXN]; back = back < tmp ? back : tmp;
bool visited[MAXN]; son++;
stack<int> topological_order; } else {
int N,E; if(i != parent)
void DFS(int node){ back = back < depth[i] ? back : depth[i];
if(visited[node]) return; } } }
visited[node] = true; low[node] = back;
for(int i=0;i<graph[node].size();i++){ if(node == 1) if(son > 1) cut++;
int dest = graph[node][i]; DFS(dest); } else cut += flag;
topological_order.push(node); } return low[node]; }
int main(){ int main() {
freopen("topological.in","r",stdin); int x, y; char c;

16
Universidad Rey Juan Carlos – RaspuTeam
while(scanf("%d", &n) == 1 && n) { if ( i == j )
memset(link, 0, sizeof(link)); tree[node] = ((sum) {array1[i],array1[i]});
memset(depth, 0, sizeof(depth)); else {
memset(low, 0, sizeof(low)); init( node * 2, i, ( i + j ) / 2 );
memset(used, 0, sizeof(used)); init( node * 2 + 1, ( i + j ) / 2 + 1, j );
while(scanf("%d", &x) == 1 && x) { sum left = tree[ node * 2 ],
while(scanf("%d%c", &y, &c) == 2) { right = tree[ node*2+1 ];
link[x][y] = 1; tree[ node ].msum = max( left.msum,
link[y][x] = 1; max( right.msum, left.m + right.m ) );
if(c == '\n') break; } } tree[ node ].m = max( left.m, right.m );}}
used[1] = 1; cut = 0; sum query( int node, int a, int b, int i, int j ) {
DFS(1, 1, 0); printf("%d\n", cut); } if ( a > b || a > j || b < i )
return 0; } return ( ( sum ) { 0, 0 } );
if ( a >= i && b <= j )
return tree[ node ];
Priority Queue (C++) sum left= query( node*2,a, (a+b)/2, i, j );
#include <bits/stdc++.h> sum right= query( node*2+1, (a+b)/2+1, b, i, j );
using namespace std; return ( ( sum ) {
struct cosa{ max(left.msum, max( right.msum,
int weight; int modificado; int inicial; left.m + right.m ) ),
bool operator<(const cosa &other)const{ return max( left.m, right.m ) } ); }
weight < other.weight; } }; void update(int node,int a,int b,int pos,int val)
int main() { priority_queue<cosa> pq; { if ( a == b && a == pos ) {
for(int i=0;i<cases;i++) { tree[ node ] = ( ( sum ) { val, val } );
cin>>numer; return; }
pq.push(cosa{numer,2,numer}); } if ( pos <= ( a + b ) / 2 ) {
cosa t1 = pq.top(); pq.pop(); update( node * 2, a, (a+b)/2, pos, val );
}
return 0; }
if ( pos > (a+b)/2) {
update( node*2+1, (a+b)/2+1,b,pos,val);}
Lazy Segment Tree (C++) sum left = tree[node*2], right=tree[node*2+1];
tree[node].msum =
#include <bits/stdc++.h> max(left.msum, max(right.msum,left.m+right.m ) );
#define MAX 100000 tree[ node ].m = max( left.m, right.m ); }
using namespace std;
struct sum { int main() {
long long int msum; int N, Q, l, r, i;
long long int m;}; char c;
int array1[ MAX + 1 ]; scanf( "%d", &N );
sum tree[ 4 * MAX + 1 ]; for ( i = 0; i < N; ++i ) {
void init( int node, int i, int j ) { scanf( "%d", array1 + i );

17
Universidad Rey Juan Carlos – RaspuTeam
} P[i][j] = -1;
init( 1, 0, N - 1 ); }
scanf( "%d", &Q ); P[1][0] = -1;
for ( i = 0; i < Q; ++i ) { for (int j = 1; bit(j) < n; j++)
scanf( "%*c%c%d%d", &c, &l, &r ); FOR (i, 1, n)
if ( c == 'U' ) if (P[i][j - 1] != -1)
update( 1, 0, N - 1, l - 1, r ); P[i][j] = P[ P[i][j - 1] ][j - 1];}
else int LCA(int u, int v) {
printf( "%lld\n", query( 1, 0, N - 1, l - int Log = 0;
1, r - 1 ).msum ); } return 0; } for (; bit(Log) <= L[u]; Log++);
/* Input: Log--;
5 for (int i = Log; i >= 0; i--)
1 2 3 4 5 if (L[u] - bit(i) >= L[v])
6 u = P[u][i];
Q 2 4 | Q 2 5 | U 1 6 | Q 1 5 | U 1 7 | Q 1 5 if (u == v) return u;
Output: 7, 9, 11, 12 for (int i = Log; i >= 0; i--)
if (P[u][i]!= -1 && P[u][i] != P[v][i])
u = P[u][i], v = P[v][i];
return T[u]; }
Last Common acestor (C++) int ancester(int u, int length) {
int Log = 0;
#include <bits/stdc++.h> for (; bit(Log) <= L[u]; Log++);
#define FOR(i, a, b) for (int i=a; i<=b; i++) Log--;
#define REP(i, n) for (unsigned int i=0; i<n; i++) for (int i = Log; i >= 0; i--)
#define Fill(ar, val) memset(ar, val, sizeof(ar)) if (length - bit(i) >= 0)
#define pb push_back u = P[u][i], length -= bit(i);
#define bit(n) (1<<(n)) return u; }
#define maxN 5005
using namespace std; void solve(int u, int v) {
int n, T[maxN], L[maxN], P[maxN][20]; if (L[u] < L[v]) swap(u, v);
vector<int> adj[maxN]; int lca_level = L[LCA(u, v)];
void build_tree(int u, int p, int lvl) { int length = L[u] + L[v] - (lca_level << 1);
if (T[u]) return; if (length % 2) {
T[u] = p; u = ancester(u, length >> 1);
L[u] = lvl; v = T[u];
REP(i, adj[u].size()) if (u > v) swap(u, v);
build_tree(adj[u][i], u, lvl + 1); } printf("The fleas jump forever
void build_array() { between %d and %d.\n", u, v);
FOR (i, 1, n) { }
P[i][0] = T[i]; else printf("The fleas meet at %d.\n",
for (int j = 1; bit(j) < n; j++) ancester(u, length >> 1)); }

18
Universidad Rey Juan Carlos – RaspuTeam
int main() { while(n--) { cin>>str;
int m, u, v; if(flag) {
while (scanf("%d", &n) && n) { tail = head;
FOR (i, 1, n) { for(i=0; str[i]; i++) {
adj[i].clear(); if(tail->end) {
T[i] = 0; flag = false;
} break; }
FOR (i, 2, n) { p = str[i]-48;
scanf("%d %d", &u, &v); if(tail->next[p]==NULL) tail->next[p] = new trie;
adj[u].pb(v); tail = tail->next[p]; }
adj[v].pb(u); tail->end = true;
} for(i=0; i<10; i++) {
build_tree(1, n + 1, 0); if(tail->next[i]) {
build_array(); flag = false; break; } } }}
scanf("%d", &m); if(flag) printf("YES\n");
while (m--) { else printf("NO\n"); } return 0;}
scanf("%d %d", &u, &v);
solve(u, v);
} } } Next Permutation (C++)
8 | 1 2 | 1 3 | 2 4 | 2 5 | 3 6 | 3 7 | 5 8 #include <bits/stdc++.h>
5 | 5 1 | 7 4 | 1 8 | 4 7 | 7 8 using namespace std;
The fleas meet at 2. The fleas meet at 1. int main() { int casos; scanf("%d", &casos);
The fleas jump forever between 2 and 5. while (casos--) {
The fleas meet at 1. int C, V, A[16] = {};
The fleas jump forever between 1 and 2 char s[16], mm[3] = "CV";
scanf("%d %d", &C, &V);
for (int i = C; i < C+V; i++)
Trie (C++)
A[i] = 1; int f = 0;
//PHONE LST TRIE do { for (int i = 0; i < C+V; i++)
#include <bits/stdc++.h> s[i] = mm[A[i]];
using namespace std; s[C+V] = '\0';
struct trie { trie *next[10]; bool end; if (f) putchar(' ');
trie() { printf("%s", s), f = 1;
for(int i=0; i<10; i++) next[i] = NULL; } while (next_permutation(A, A+C+V));
end = false; } }; puts(""); }return 0; }
int main() {
int t, n, i, p;
char str[15]; bool flag; cin>>t;
while(t--) {
cin>>n; trie *head, *tail;
head = new trie; flag = true;

19
Universidad Rey Juan Carlos – RaspuTeam
//OUTPUT: a vector containing the longest increasing subsequence
#include <bits/stdc++.h>
int Ceil(vector<int> &v, int l, int r, int key) {
Hojas de un árbol balanceado (C++) while (r-l > 1) { int m = l + (r-l)/2;
if (v[m] >= key) r = m;
#include <iostream> else l = m; } return r; } int LIS(vector<int> &v) {
using namespace std; if (v.size() == 0) return 0;
int main() { int n=1; long long int sum=0; vector<int> tail(v.size(), 0);
while(n!=0) { int length = 1; tail[0] = v[0];
cin >> n; int arr[n]; arr[0]=n; for (size_t i = 1; i < v.size(); i++) {
if(n!=0) { if (v[i] < tail[0]) tail[0] = v[i];
for(int i = 1 ; i <= n ; i++) { else if (v[i] > tail[length-1])tail[length++]=v[i];
cin >> arr[i]; if((2 * i) > n) else tail[Ceil(tail, -1, length-1, v[i])] = v[i];
sum += arr[i]; } cout<<sum<<"\n"; } return length;}
sum=0; } }return 0; }

Knuth-Morris-Pratt (C++)
Sets (C++)
#include <bits/stdc++.h>
#include <bits/stdc++.h> using namespace std;
using namespace std; void kmp(const string &needle,const string
int main(){ &haystack){ int m = needle.size();
int n; cin>>n; vector<int> border(m + 1); border[0] = -1;
while(n--) { for (int i = 0; i < m; ++i) {
int p; cin>>p; border[i+1] = border[i];
map<string,int> a; cin.ignore(); while (border[i+1>-1 and needle[border[i+1]] !=
for(int i=0; i<p;i++) { needle[i]) { border[i+1] = border[border[i+1]]; }
string m; getline(cin,m); border[i+1]++; }
if(a.insert(pair<string,int>(m,1)).second==false) int n = haystack.size(); int seen = 0;
{ int k = a.find(m)->second; k++; for (int i = 0; i < n; ++i){
map<string, int>::iterator it = a.find(m); while (seen > -1 and needle[seen] != haystack[i]) {
if (it != a.end()) seen = border[seen]; }
it->second = k; } } if (++seen == m) { printf("%d\n", i - m + 1);
cout<<endl; seen = border[m]; } } }
map<string,int>::iterator it = a.begin(); int main(){ int m; bool first = true;
for (it=a.begin(); it!=a.end(); ++it) while (scanf("%d",&m)==1) {
std::cout << it->first << it->second << '\n'; } if (!first) puts(""); first = false;
return 0; } string needle; getline(cin, needle);
getline(cin, needle);
string haystack; getline(cin, haystack);
Longest Increasing Subsequence (C++) kmp(needle, haystack); } return 0;}
// INPUT: a vector of integers X= 0, 8, 4, 12, 2, 10, 6 || LCS= 0,8,12

20
Universidad Rey Juan Carlos – RaspuTeam
Búsqueda binaria y lineal (C++)
Latitud/Longitud (C++)
//Converts from rectangular coordinates to latitude
#include <bits/stdc++.h> /longitude and vice versa. Uses degrees (not
using namespace std; radians).
int lineal_search(int *array, int searched, int #include <bits/stdc++.h>
arraySize) { using namespace std;
for (int i = 0; i< arraySize; i++) { struct ll { double r, lat, lon; };
if (searched == array[i]) { return array[i]; } struct rect { double x, y, z; };
} return 0;} ll convert(rect& P) { ll Q;
int binary_search(int *array, int searched, int Q.r = sqrt(P.x*P.x+P.y*P.y+P.z*P.z);
arraySize) { int first = 0, middle, last = arraySize - Q.lat = 180/M_PI*asin(P.z/Q.r);
1; Q.lon = 180/M_PI*acos(P.x/sqrt(P.x*P.x+P.y*P.y));
while (first<=last) { middle = (first + last) / 2; return Q; }
if (searched == array[middle]) return array[middle]; rect convert(ll& Q) { rect P;
else { P.x = Q.r*cos(Q.lon*M_PI/180)*cos(Q.lat*M_PI/180);
if (array[middle] > searched) last = middle - 1; P.y = Q.r*sin(Q.lon*M_PI/180)*cos(Q.lat*M_PI/180);
else first = middle + 1; P.z = Q.r*sin(Q.lat*M_PI/180);
} } return -1; } return P; }
int main() { int main() { rect A; ll B;
int arraySize, searched; cin >> arraySize; A.x = -1.0; A.y = 2.0; A.z = -3.0;
int array[arraySize]; cin >> searched; B = convert(A);
lineal_search(array, searched, arraySize); cout << B.r << " " << B.lat << " " << B.lon <<
binary_search(array, searched, arraySize); endl; A = convert(B);
return 0; } cout << A.x << " " << A.y << " " << A.z << endl; }

QuickSort (C++) Números Primos (C++)


#include <bits/stdc++.h> //2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37,41,
int values[] = { 40, 10, 100, 90, 20, 25 }; 43, 47, 53, 59, 61, 67, 71,73, 79, 83, 89, 97
int compare (const void * a, const void * b) { #include <bits/stdc++.h>
return ( *(int*)a - *(int*)b ); } using namespace std;
int main (){ int n; bool prime(int n) {
qsort (values, 6, sizeof(int), compare); if (n<2) return false; if (n<=3) return true;
for (n=0; n<6; n++) printf ("%d ",values[n]); if (!(n%2) || !(n%3)) return false;
return 0; } for (int i=5;i*i<=n;i+=6)
if (!(n%i) || !(n%(i+2))) return false;
return true; }

21
Universidad Rey Juan Carlos – RaspuTeam
Constantes (C++) Maneras de Leer en ficheros (C++)
if(scanf(“%d”,&cases!=EOF) || ==1
PI: 4 * atan(1) while(getline(cin,str))
Distancia Euclediana: sqrt(pow(q[i].x-actual.x,2.0)+ pow(q[i].y-
actual.y,2.0)+ pow(q[i].z-actual.z,2.0));
Maximum submatrix (C++)
Distancia Manhattan: abs(x-x)+abs(y-y)
#include<iostream>
INF: 0x3F3F3F3F using namespace std;
//number too large. use powl instead of pow. int a[150][150]={0};
powl(a, b) int c[200]={0};
(int)round(p, (1.0/n)) int maxarray(int n) {
printf("%.1f\n", (a * b)/2); int b=0, sum=-100000000;
void copy(first, last, result); for (int i=1;i<=n;i++) {
void swap(a,b); if (b>0) b+=c[i]; else b=c[i];
void swap(first1, last1, first2); if (b>sum) sum=b; } return sum; }
void replace(first, last, old_value, new_value); int maxmatrix(int n) {
void replace_if(first, last, pred, new_value); int sum=-100000000, max=0;
void reverse(first, last); for (int i=1;i<=n;i++) {
void reverse_copy(first, last, result); for (int j=1;j<=n;j++) c[j]=0;
// Searching for (int j=i;j<=n;j++) {
int find(const string &s2, int pos1 = 0); for (int k=1;k<=n;k++) c[k]+=a[j][k];
int rfind(const string &s2, int pos1 = end); max=maxarray(n);
int find_first_of(const string &s2, int pos1 = 0); if (max>sum) sum=max; } } return sum; }
int find_last_of(const string &s2, int pos1 = end); int main(void) { int n=0; cin >> n;
int find_first_not_of(const string &s2,int pos1=0); for (int i=1;i<=n;i++)
int find_last_not_of(const string &s2,int pos1=end); for (int j=1;j<=n;j++)
// Insert, Erase, Replace cin >> a[i][j]; cout << maxmatrix(n); return 0;}
string& insert(int pos1,const string &s2);
string& insert(int pos1,int repetitions, char c);
string& erase(int pos = 0,int len = npos);
string& replace(int pos1,int len1, const string &s2);
string& replace(int pos1, int len1,int
repetitions, char c); int i = 22;
s1 << "Hello world! " << i;
cout << s1.str() << endl;

22
Universidad Rey Juan Carlos – RaspuTeam
Partitions Integer (C++) {
memset(mark,false,sizeof(mark));
//4 = 3 + 1 , 2 + 2 , memset(memo,0,sizeof(memo));
2+1+1, getline(cin,Y);
1 + 1 +1 + 1 printf("%d\n", lcs(X.length(),Y.length()));
void printAllUniqueParts(int n) { }
int p[n]; int k = 0; p[k] = n; return 0; }
while (true) {
printArray(p, k+1);
int rem_val = 0; Longest Increasing Common Subsequence (C++)
while (k >= 0 && p[k] == 1) {
rem_val += p[k]; k--; } // 2 3 1 6 5 4 6 AND 1 3 5 6 the LCIS is 3 5 6.
if (k < 0) return; //Dada una lista de numberos de longitud n,
p[k]--; extrae a que es la mayor subsecuencia de aumento
rem_val++; O(nlogn)
while (rem_val > p[k]) { //INPUT: a vector of integers // Posible solucion
p[k+1] = p[k]; //X= 0, 8, 4, 12, 2, 10, 6 || LCS= 0,8,12
rem_val = rem_val - p[k]; //OUTPUT: a vector containing the longest increasing
k++; } subsequence
p[k+1] = rem_val; k++; } } #include <bits/stdc++.h>
using namespace std;
int Ceil(vector<int> &v, int l, int r, int key) {
Longest Common Subsequence(C++) while (r-l > 1) { int m = l + (r-l)/2;
if (v[m] >= key) r = m;
#include<bits/stdc++.h> else l = m; } return r; }
using namespace std; int LIS(vector<int> &v) {
string X; if (v.size() == 0) return 0;
string Y; vector<int> tail(v.size(), 0);
int memo[1005][1005]; int length = 1;
bool mark[1005][1005]; tail[0] = v[0];
int lcs(int m, int n ) for (size_t i = 1; i < v.size(); i++) {
{ if (v[i] < tail[0]) tail[0] = v[i];
if (m == 0 || n == 0) return 0; else if (v[i] > tail[length-1])tail[length++]=v[i];
int &best= memo[m][n]; else tail[Ceil(tail, -1, length-1, v[i])] = v[i];
if(mark[m][n]) return best; } return length;}
mark[m][n]=true;
if (X[m-1] == Y[n-1]) return best=1+lcs(m-1, n-1);
return best=max(lcs(m, n-1),lcs(m-1, n));
}
int main()
{
while(getline(cin,X))

23
Universidad Rey Juan Carlos – RaspuTeam
Partitions of sets – Bell Numbers (C++) #include <bits/stdc++.h>
using namespace std;
#include<iostream> struct point{
using namespace std; double x,y;
int countP(int n, int k) { point(){}
if (n == 0 || k == 0 || k > n) return 0; point(double a,double b){
if (k == 1 || k == n) return 1; x=a;y=b;
return k*countP(n-1, k) + countP(n-1, k-1); } }
int main() { bool operator<(const point &other)const{
int a=0; return x < other.x || (x==other.x && y <
for(int i=0; i<5;i++) other.y); } };
//Sin for solo devuelve en X subsets int L,S;
de esa cantidad point points[MAXN];
a+=countP(5, i); a++; int orientation(point a,point b,point c){
cout<<a<<endl; return 0; } int v = (b.y-a.y) * (c.x-b.x) - (b.x-a.x) *
//1,1,2,5,15,52 Bell Numbers (c.y-b.y);
if(!v) return 0; //colinear
FastInput (C++) return v>0?1:2; // clock or counterclock wise }
double cross(const point &O, const point &A, const
inline int getchar_unlocked() { return getchar();} point &B)
{ return (A.x - O.x) * (B.y - O.y) - (A.y - O.y)
inline void fastInput(int &n){ * (B.x - O.x); }
char ch; vector<point> getConvexHull(){
int sign = 1; int n = L, k = 0;
while(ch = getchar_unlocked(), isspace(ch)) { vector<point> H(2*n);
// Sort points lexicographically
}; sort(points, points+n);
n = 0; // Build lower hull
if(ch == '-') for (int i = 0; i < n; ++i) {
sign = -1; while (k >= 2 && cross(H[k-2], H[k-1],
else n = ch - '0'; points[i]) <= 0) k--;
while(ch = getchar_unlocked(), isdigit(ch)) H[k++] = points[i]; }
n = (n << 3) + (n << 1) + ch - '0'; for (int i = n-2, t = k+1; i >= 0; i--) {
n *= sign; } while (k >= t && cross(H[k-2], H[k-1],
points[i])
<= 0) k--;
H[k++] = points[i]; }
H.resize(k-1);
return H;}
//Comprueba si el punto q pertenece al segmento pr
bool onSegment(point p, point q, point r) {

24
Universidad Rey Juan Carlos – RaspuTeam
if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) && for(int i = 0,j = n - 1;i < n;j = i++){
q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y)) double dx = poly[j].x - poly[i].x;
return true; double dy = poly[j].y - poly[i].y;
return false; }
bool doIntersect(point p1, point q1, point p2, point if((poly[i].y <= P.y + 1e-10 && P.y < poly[j].y) ||
q2) { (poly[j].y <= P.y + 1e-10 && P.y < poly[i].y))
// Find the four orientations needed for general if(P.x - 1e-10 < dx * (P.y-poly[i].y)/dy+poly[i].x)
and special cases in ^= 1; }
int o1 = orientation(p1, q1, p2); return in; }*/
int o2 = orientation(p1, q1, q2); double signed_area(vector<point> &poly){
int o3 = orientation(p2, q2, p1); int n = poly.size();
int o4 = orientation(p2, q2, q1); if(n < 3) return 0.0;
if (o1 != o2 && o3 != o4)
return true; double S = 0.0;
if (o1 == 0 && onSegment(p1, p2, q1)) return true;
if (o2 == 0 && onSegment(p1, q2, q1)) return true; for(int i = 1;i <= n;++i)
if (o3 == 0 && onSegment(p2, p1, q2)) return true; S += poly[i % n].x * (poly[(i + 1) % n].y - poly[i -
if (o4 == 0 && onSegment(p2, q1, q2)) return true; 1].y);
return false; } return S / 2; }
int pointInsidePolygon(point p, vector<point> polygon){ int main(){
int n = (int)polygon.size(); while(scanf("%d",&L)!=EOF){
if (polygon.size() < 3) FOR(i,0,L){
return false; RF(points[i].x); RF(points[i].y);
if (cross(polygon[0], p, polygon[1]) > 1e-10) }
return false; vector<point> convex_hull = getConvexHull();
if (cross(polygon[0], p, polygon[n-1]) < -1e-10) int cnt = 0;
return false; RI(S);
int l = 2, r = n-1; FOR(i,0,S){
int line = -1; int x,y; RI(x); RI(y);
while (l <= r) { cnt += pointInsidePolygon(point(x,y),
int mid = (l + r)>>1; convex_hull); }
if (cross(polygon[0],p, polygon[mid]) > -1e-10) { printf("%d\n",cnt); } return 0; }
line = mid; Among oldest and most well-studied problems in
r = mid - 1; computational geometry problems.Robot motion planning.
} else l = mid + 1; } Shortest perimeter fence enclosing P.
return cross(polygon[line-1], p, polygon[line]) < Smallest area polygon enclosing P.
1e-10; } Unique convex polygon whose vertices are points in P that
/*bool pointInsidePolygon(point P, vector<point> poly){ encloses P.
int n = poly.size(); Smallest convex set containing all N points (i.e.,
bool in = 0; intersection of all convex sets containing the N points).

25

You might also like