0% found this document useful (0 votes)
16 views12 pages

Kactl

Uploaded by

idaniellavargas
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views12 pages

Kactl

Uploaded by

idaniellavargas
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

Universidad Peruana de Ciencias Aplicadas

Monaschinas
Dobby, Sebastian, Jack

2023-10-07
1 Contest 1 troubleshoot.txt 16 lines
if(left >= w[pos]) {
ans = max(ans, v[pos] + solve(pos+1, left-w[pos]));
Wrong answer: }
2 Dynamic Prog 1 - Formato de salida (falta un ’n’ o ’ ’).
- Debuggear el codigo con couts (sin fast input). vis[pos][left] = 1;
- Checkear si limpia memoria por cada test case. return dp[pos][left] = ans;
3 Data structures 3 }
Runtime error:
- Lectura fuera del vector.
4 Number theory 4 - Division entre 0.
int main(){
solve(0, C);
}
5 Graph 4 Time limit exceeded:
- Recursion infinita.
- Escribir la complejidad temporal.
6 Strings 9 KnapsackIter.h
Tips: Description: Knapsack iterativo.
- Trabajar en equipo (discutir ideas, revisar codigo, etc). Time: O (N ∗ C) c72d6b, 24 lines
7 Game theory 10 - Tomar un descanzo (ej. ir a los servicios higienicos). int n, C;
int v[N];
8 Various 10 int w[N];
Dynamic Prog (2)
// Memoria O(N)

Contest (1) 2.1 Fundamentals int solve(){


vector<int> last(C+1);
SumaRango.h vector<int> dp(C+1);
Description: Suma en rangos. for(int pos = n-1; pos >= 0; pos--){
template.cpp 19 lines Time: O (N ) for(int left = 0; left <= C; left++){
eda838, 22 lines
#include <bits/stdc++.h> int a[N];
using namespace std; int ans = last[left];
int dif[N]; if(left >= w[pos]){
typedef long long ll; ans = max(ans, v[pos] + last[left - w[pos]]);
int main(){ }
cin >> n >> q; dp[left] = ans;
void solve(){ for(int i = 1; i <= n; i++){ }
cin >> a[i]; last = dp;
} dif[i] = a[i] - a[i-1]; }
} return last[C];
int main() {
ios_base::sync_with_stdio(0); }
while(q--){ int main(){
cin.tie(0); int l, r, x; solve();
cin >> l >> r >> x; }
int tc = 1; dif[l] += x;
// cin >> tc ; dif[r+1] -= x;
while(tc--){ }
solve(); for(int i = 1; i <= n; i++) a[i] = dif[i] + a[i-1]; maxsubarray1D.h
} for(int i = 1; i <= n; i++){ Description: Terminando en ’i’.
} cout << a[i] << " "; Time: O (N ) fd4563, 21 lines
}
// memo[ i ] : Maxima suma de arreglo que termina en la posicion ’
return 0;
.bashrc 3 lines }
i ’.
// memo[ i ] : Toma solo a [ i ] o ( . . . , a [ i −1], a [ i ] )
alias c=’g++ -Wall -Wconversion -Wfatal-errors -g -std=c++14 \ // memo[ i ] : max(a [ i ] , a [ i ] + memo[ i −1])
-fsanitize=undefined,address’ KnapsackRec.h // memo[ i ] : a [ i ] + max(0 , memo[ i −1])
xmodmap -e ’clear lock’ -e ’keycode 66=less greater’ #caps = <> Description: Knapsack recursivo. const int N = 1e5 + 5;
Time: O (N ∗ C) 32b1af, 26 lines const int inf = 1e9;

.vimrc 6 lines
const int N = 1e2 + 5; // Limite de ”n”
int n;
const int W = 1e4 + 5; // Limite de capacidad
set cin aw ai is ts=4 sw=4 tm=50 nu noeb bg=dark ru cul int a[N];
int n, C;
sy on | im jk <esc> | im kj <esc> | no ; : int memo[N];
int v[N];
" Select region and then type :Hash to hash your selection. int w[N];
" Useful for verifying that there aren’t mistypes. int solve(){
ca Hash w !cpp -dD -P -fpreprocessed \| tr -d ’[:space:]’ \ for(int i = 0; i < n; i++){
// Memoria O(N∗C)
\| md5sum \| cut -c-6 if(i == 0) {
int dp[N][W];
memo[i] = a[i];
bool vis[N][W];
} else {
hash.sh memo[i] = max(a[i], a[i] + memo[i-1]);
3 lines int solve(int pos, int left){
}
if(pos == n) return 0;
# Hashes a file, ignoring all whitespace and comments. Use for }
if(vis[pos][left]) return dp[pos][left];
# verifying that code was correctly typed. return *max_element(memo, memo+n);
cpp -dD -P -fpreprocessed | tr -d ’[:space:]’| md5sum |cut -c-6 }
int ans = solve(pos+1, left);
plate .bashrc .vimrc hash troubleshoot SumaRango KnapsackRec KnapsackIter maxsubarray1D maxsubarray1Dprefix maxsubarray2D maxsubarray2Dprefix SumaStaticQuery LCS LCSfind
KTH 2
maxsubarray1Dprefix.h } }
Description: Diferencia de prfijos return memo[n][m];
Time: O (N ) db4a4e, 31 lines maxsubarray2Dprefix.h }
// S[ i ] = a [ 1 ] + . . . + a [ i ] Description: F[i][j]: Suma hasta fila i de la columna j-
// suma( l , r ) = S[ r ] − S[ l −1] Time: O N 3 4e693e, 28 lines LCSfind.h
ll F[N][N]; Description: Find the path.
// F[ i ] : Maxima suma de arreglo que termina en pos ’ i ’ Time: O N 2 4c3fb7, 33 lines
// F[ i ] : max(S[ r ] − S[ l −1]) donde 0 <= l < r void solve(){
// F[ i ] : S[ r ] + max(−S[ l −1]) donde S[ r ] se itera y max(−S[ l −1]) const int N = 100, M = 100, inf = 1e9;
// preprocesar int memo[N][N];
se procesa en marcha for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){ string solve(){
// S[ r ] : prefix F[i][j] = a[i][j];
// S[ l −1]: bestprefix for(int i = 1; i <= n; i++){
if(i) F[i][j] += F[i-1][j]; for(int j = 1; j <= m; j++){
const int N = 1e5 + 5; }
const int inf = 1e9; int cur = 0;
} // Cuidado con memo [−1]
// suma en 2D if(s[i-1] == t[j-1]) cur = max(cur, 1 + memo[i-1][j
int n; int ans = INT_MIN;
int a[N]; -1]);
for(int r1 = 0; r1 < n; r1++){ else cur = max(memo[i-1][j], memo[i][j-1]);
int memo[N]; for(int r2 = r1; r2 < n; r2++){
int prefix = 0, mini = 0; memo[i][j] = cur;
int solve(){ for(int i = 0; i < n; i++){
ll prefix = 0; }
int col = F[r2][i]; }
ll mini = 0; if(r1){
ll ans = -inf; col -= F[r1-1][i];
for(int i = 0; i < n; i++){ string ans = "";
} int i = n, j = m;
prefix += a[i]; prefix += col;
if(ans < prefix - mini){ while(i > 0 and j > 0){
if(ans < prefix - mini) ans = prefix - mini; if(s[i-1] == t[j-1]){
ans = prefix - mini; if(mini > prefix) mini = prefix;
} ans.push_back(s[i-1]);
} i -= 1;
if(mini > prefix){ // be s t p r e f ix para i+1 }
mini = prefix; j -= 1;
} } else {
} cout << ans;
} if(memo[i-1][j] > memo[i][j-1]){
} i -= 1;
return ans;
} } else {
SumaStaticQuery.h j -= 1;
Description: Query en un array estático. }
maxsubarray2D.h Time: O (N ) }
Description: S[i][j]: Suma hasta fila i, columna j. 6186d8, 14 lines
}
Time: O (N ) 769e50, 30 lines
int main(){ reverse(ans.begin(), ans.end());
for(int i = 0; i < n; i++){ return ans;
ll S[N][N]; cin >> a[i]; }
a[i] += (i-1 >= 0 ? a[i-1] : 0);
void solve(){ }
// preprocesar while(q--){ LCSfollow.h
for(int i = 0; i < n; i++){ int l, r; Description: Follow the path.
for(int j = 0; j < n; j++){ cin >> l >> r; Time: O N 2
int suma = a[i][j]; ffa3d3, 41 lines
r--;
if(i) suma += S[i-1][j]; ll suma = a[r] - (l-1 >= 0 ? a[l-1] : 0); const int N = 100, M = 100, inf = 1e9;
if(j) suma += S[i][j-1]; cout << suma << "\n";
if(i and j) suma -= S[i-1][j-1]; } int memo[N][N];
S[i][j] = suma; return 0; int choice[N][N];
} }
} string solve(){
// suma en 2D for(int i = 1; i <= n; i++){
int ans = INT_MIN; 2.2 Subsequence for(int j = 1; j <= m; j++){
for(int r1 = 0; r1 < n; r1++){ LCS.h // Cuidado con memo [−1]
for(int r2 = r1; r2 < n; r2++){ Description: Longest Common Subsequence if(s[i-1] == t[j-1]) {
for(int c1 = 0; c1 < n; c1++){ Time: O (N ∗ C) memo[i][j] = 1 + memo[i-1][j-1];
for(int c2 = c1; c2 < n; c2++){ 300365, 12 lines choice[i][j] = 0;
int suma = S[r2][c2]; int solve(){ }
if(r1) suma -= S[r1-1][c2]; for(int i = 1; i <= n; i++){ else {
if(c1) suma -= S[r2][c1-1]; for(int j = 1; j <= m; j++){ if(memo[i-1][j] > memo[i][j-1]){
if(r1 and c1) suma += S[r1-1][c1-1]; int ans = 0; memo[i][j] = memo[i-1][j];
ans = max(ans, suma); // Cuidado con memo [−1] choice[i][j] = 1;
} if(s[i-1] == t[j-1]) ans = max(ans, 1 + memo[i-1][j } else {
} -1]); memo[i][j] = memo[i][j-1];
} else ans = max(memo[i-1][j], memo[i][j-1]); choice[i][j] = 2;
} memo[i][j] = ans; }
cout << ans; } }
KTH LIS SegmentTree FenwickTree MinQueue SQRT 3
} SegmentTree.h
} Description: Estructura de consulta y actualizacion en rangos. ST index- struct MinStack {
ado en 0, pero ’pos’ inicia en 1. stack<pair<int, int>> S;
string ans = ""; Time: O (log N ) void push(int x){
4fd1d0, 35 lines
int i = n, j = m; S.push(make_pair(x, min(x, S.empty() ? INT_MAX : S.top
while(i > 0 and j > 0){ const int N = 1e5 + 5; ().second)));
if(choice[i][j] == 0){ const int MAX = 4*N; }
ans.push_back(s[i-1]); ll st[MAX]; void pop(){
i -= 1; if(!S.empty()){
j -= 1; void build(int pos=1, int l=0, int r=n-1){ S.pop();
} else if(choice[i][j] == 1){ if(l == r){ }
i -= 1; st[pos] = a[l]; }
} else { } bool empty(){
j -= 1; int mi = (l+r)/2; return S.empty();
} build(2*pos, l, mi); }
} build(2*pos+1, mi+1, r); int top(){
reverse(ans.begin(), ans.end()); st[pos] = st[2*pos] + st[2*pos+1]; return S.empty() ? -1 : S.top().first;
return ans; } }
} int get_min(){
// x , y (query) return S.empty() ? -1 : S.top().second;
// l , r (subarray) }
LIS.h ll query(int x, int y, int pos, int l, int r){ };
Description: Longest Increasing Subsequence if(y < l or x > r) return 0;
Time: O (N ∗ logN ) if(l >= x and r <= y) return st[pos]; struct MinQueue{
ca343f, 41 lines int mi = (l+r)/2; MinStack in, out;
const int N = 100; ll left = query(x, y, 2*pos, l, mi); void push(int x){
int n; ll right = query(x, y, 2*pos+1, mi+1, r); in.push(x);
int a[N]; return left + right; }
vector<int> vec; } void pop(){
if(out.empty()){
void add(int left, int right, int val){ void update(int x, int y, int pos, int l, int r){ while(!in.empty()){
if(left == right){ if(l == r){ out.push(in.top());
if(vec[left] >= val){ st[pos] = y; in.pop();
vec[left] = val; return; }
} else { } }
vec.emplace_back(val); int mi = (l+r)/2; if(!out.empty()){
} if(x <= mi) update(x, y, 2*pos, l, mi); out.pop();
return; else update(x, y, 2*pos+1, mi+1, r); }
} st[pos] = st[2*pos] + st[2*pos+1]; }
int mid = (right - left)/2; } bool empty(){
return in.empty() and out.empty();
if(val <= vec[mid]){ }
add(left, mid, val);
FenwickTree.h int front(){
Description: Estructura de prefijo que permite modificaciones y consulta
} else { if(out.empty()){
en O(log N).
add(mid+1, right, val); while(!in.empty()){
Time: O (log N ) e2642f, 18 lines
} out.push(in.top());
} const int N = 1000000 + 5; in.pop();
void imprime_vector(){ ll ft[N]; }
for(int i = 0; i < vec.size(); i++){ }
cout << vec[i] << " "; void update(int pos, int val){ return out.empty() ? -1 : out.top();
} while(pos <= MAXI){ }
cout << "\n"; ft[pos] += val; int get_min(){
} pos += (pos & -pos); return min(in.empty() ? INT_MAX : in.get_min(),
int main(){ } out.empty() ? INT_MAX : out.get_min());
scanf("%d", &n); } }
for(int i = 0; i < n; i++) cin >> a[i]; } minqueue;
vec.push_back(a[0]); // i n i c i a l ll query(int pos){
ll res = 0;
for(int i = 1; i < n; i++){ while(pos > 0){ SQRT.h
add(0, vec.size()-1, a[i]); res += ft[pos]; Description:
√ Estructura
 de consulta y actualizacion en raices.
imprime_vector(); pos -= (pos & -pos); Time: O N
912018, 38 lines
} }
return res; // N,Q <= 1e5
cout << vec.size() << "\n"; } const int N = 1e5 + 5;
return 0; const int SQRT = 450;
}
MinQueue.h int n, q;
Description: Estructura de consulta en O(1) amortizado y actualización int a[N];
O(1). int bsize;
Data structures (3) Time: O (log N ) 5a7abe, 54 lines ll sum[SQRT];
KTH Primo FactoresPrimos Tdprimes Criba Euclides EuclidesExtended UniversalSink NumberPaths 4

void build(){ const int N = 100000000 + 1;


Graph (5)
for(int i = 0; i < n; i++){
sum[i / bsize] += a[i]; vector<int> primes;
} bitset<N> composite; 5.1 Fundamentals
}
int main() {
UniversalSink.h
ll query(int l, int r) { Description: Find universal sink interactivo.
ll res = 0; for(int i = 2; i < N; i++) { Time: O (3 ∗ N )
if(not composite[i]) primes.emplace_back(i); 23ce8d, 43 lines

while(l % bsize != 0 and l <= r){ for(int p : primes) { int main(){


res += a[l]; if(i * p >= N) break; int n;
l += 1; composite[i * p] = true; cin >> n;
} if(i % p == 0) break;
// l + bsize − 1 <= r } int j = 0;
while(l + bsize - 1 <= r){ } for(int i = 1; i < n; i++){
res += sum[l/bsize]; for(int i = 0; i < primes.size(); i += 100) printf("%d\n", cout << "? " << i+1 << " " << j+1 << "\n";
l += bsize; primes[i]); fflush(stdout);
} return 0; bool e;
while(l <= r){ } cin >> e;
res += a[l]; if(e){
l += 1; Criba.h continue;
} Description: Criba para hallar numeros primos. } else {
return res; Time: O (N ) j = i;
3be3f3, 11 lines }
}
void update(int pos, int val){ void solve(int n){ }
int idx = pos / bsize; vector<int> prime(n+1, true); int row = 0;
sum[idx] -= a[pos]; for(int i = 0; i < n; i++){
sum[idx] += val; for(int i = 2; i <= n; i++){ cout << "? " << i+1 << " " << j+1 << "\n";
a[pos] = val; if(prime[i]){ fflush(stdout);
} for(int j = i*2; j <= n; j += i){
prime[j] = false; bool e;
} cin >> e;
Number theory (4) }
}
}
row += e;

} int col = 0;
Primo.h for(int i = 0; i < n; i++){
Description: Verifica si un numero es primo. cout << "? " << j+1 << " " << i+1 << "\n";
Time: O (logN ) Euclides.h fflush(stdout);
2f50f9, 8 lines Description: Euclides para hallar mcd (gcd).
bool primo(int n){ Time: O (logN ) 21d9fc, 4 lines bool e;
for(int i = 2; i*i <= n; i++){
int gcd(int a, int b){ cin >> e;
if(n % i == 0){
if(a == 0) return b; col += e;
return 0;
return gcd(b % a, a); }
}
} if(row == n-1 && col == 0){
}
cout << "! " << j+1 << "\n";
return !;
fflush(stdout);
} EuclidesExtended.h } else {
Description: Euclides extendido ax + by = gcd(a, b) cout << "! " << -1 << "\n";
FactoresPrimos.h Time: O (logN ) 343534, 20 lines fflush(stdout);
Description:
√ Encuentra
 los factores primos. int gcdExtended(int a, int b, int *x, int *y){ }
Time: O N // Base case return 0;
7ade7a, 13 lines }
if(a == 0){
void solve(){ *x = 0;
for(int i = 2; 1ll*i*i <= n; i++){ *y = 1;
if(n % i == 0){ return b; NumberPaths.h
while(n % i == 0){ } Description: Encuentra el número de caminos con longitud l, para ello usa
cout << i << " "; int x1, y1; binary exponentation.
n /= i; int gcd = gcdExtended(b % a, a, &x1, &y1); Time: O (N ∗ N ∗ logN ) 1f59af, 54 lines
}
} const int MOD = 1e9 + 7;
*x = y1 - (b/a)*x1;
} *y = x1;
if(n > 1){ typedef vector<int> vi;
return gcd;
cout << n << "\n"; typedef vector<vector<int>> vvi;
}
}
} vvi multiply(vvi a, vvi b, int n){
int main(){
vvi c (n, vi(n));
int x, y;
// multiply
Tdprimes.h int gcd = gcdExtended(a, b, &x, &y);
for(int i = 0; i < n; i++){
Description: Encuentra los factores primos. cout << x << y << gcd;
for(int j = 0; j < n; j++){
Time: O (logN ) }
0bdcc4, 17 lines for(int k = 0; k < n; k++){
KTH BFS BFSfrontier Dijkstra BellmanFord 5
c[i][j] = (c[i][j] + 1ll * a[i][k] * b[k][j]) % dis[v] = dis[u] + 1; // O(ElogE)
MOD; vis[v] = 1; vector<ll> d(n, inf);
} Q.push(v); d[s] = 0;
} }
} } priority_queue<pair<ll, int>, vector<pair<ll, int>>,
return c; } greater<pair<ll, int>>> Q;
} Q.emplace(make_pair(0, s));
int main(){
vvi exp_power(vvi a, int n, int l){ cin >> n; while(!Q.empty()){
vvi result (n, vi(n)); for(int i = 0; i < n; i++){ int u;
// identity matrix int u, k; ll dis;
for(int i = 0; i < n; i++) result[i][i] = 1; cin >> u >> k; tie(dis, u) = Q.top();
u--; Q.pop();
while(l > 0){ for(int j = 0; j < k; j++){ if(dis != d[u]) continue;
if(l & 1){ int v;
result = multiply(result, a, n); cin >> v; //for (auto [ v , w] : G[u] ){ // Feature in C++ 17
} v--; for(auto pair : G[u]){
l /= 2; G[u].push_back(v); int v;
a = multiply(a, a, n); } ll w;
} } tie(v, w) = pair;
return result; bfs(0);
} for(int i = 0; i < n; i++){ if(d[v] > d[u]+ w){
cout << i+1 << " " << (dis[i] == inf ? -1 : dis[i]) << d[v] = d[u] + w;
int main(){ "\n"; Q.emplace(make_pair(d[v], v));
int n, l; } }
cin >> n >> l; return 0; }
vvi a(n, vi(n)); } }
for(int i = 0; i < n; i++){
for(int i = 0; i < n; i++){ printf("%lld%c", d[i], " \n"[i+1 == n]);
for(int j = 0; j < n; j++){ BFSfrontier.h }
cin >> a[i][j]; Description: Encuentra el camino màs corto de un nodo hacia los demas. }
} Todas las aristas tienen el mismo peso.
} Time: O (|V | + |E|) 120650, 26 lines int main(){
vvi al = exp_power(a, n, l); const int inf = 1e9 + 10; // Inout
// cout << ” r e s u l t matrix \n”; const int N = 1e5 + 5; G[u].emplace_back(make_pair(v, w));
// for ( int i = 0; i < n; i++){ G[v].emplace_back(make_pair(u, w));
// for ( int j = 0; j < n; j++){ vector<int> G[N]; // Process
// cout << al [ i ] [ j ] << ” ”; bool vis[N]; Dijsktra(0);
// } int dis[N]; }
// cout << ”\n”;
// } void bfs(int s){
cout << al[0][n-1]; for(int i = 0; i < n; i++) dis[s] = inf; BellmanFord.h
return 0; vector<int> front = {s}; Description: Calcula el camino más corto de s en un grafo, este puede tener
} dis[s] = 0; aristas negativas, pero no puede tener ciclos negativos.
vis[s] = 1; Time: O (V ∗ E) 340af8, 32 lines

BFS.h const int N = 100000 + 5;


while (!front.empty()){ const long long inf = 1e18 + 10;
Description: Encuentra el camino màs corto de un nodo hacia los demas. vector<int> cur;
Todas las aristas tienen el mismo peso.. int n, m;
for(int u : front){ long long d[N];
Time: O (|V | + |E|) 3be3b8, 45 lines for(int v : G[u]){ vector<tuple <int, int, int>> edges;
const int N = 1e2 + 5; if(vis[v]) continue;
const int inf = 1e9 + 5; dis[v] = dis[u] + 1; bool Bellman(int s){
vis[v] = 1; for(int i = 0; i < n; i++) d[i] = inf * (i != s);
int n; cur.push_back(v); int last = 0;
vector<int> G[N]; }
int dis[N]; } for(int i = 1; i <= n; i++){
bool vis[N]; swap(cur, front); bool relaxed = false;
} for(auto e : edges){
void bfs(int s){ } int u, v, w;
for(int u = 0; u < n; u++) dis[u] = inf; tie(u, v, w) = e;
queue<int> Q; Dijkstra.h if(d[u] < inf and d[v] > d[u] + w){
dis[s] = 0; Description: Distancia más corta de un nodo hacia los demas. No acepta d[v] = d[u] + w;
vis[s] = 1; aristas negativas. relaxed = true;
Q.push(s); Time: O (E ∗ logE) }
while (!Q.empty()){ f166fe, 42 lines }
int u = Q.front(); int n, m; if(not relaxed) break;
Q.pop(); vector<pair<int, int>> G[N]; last = i;
for(int v : G[u]){ }
if(vis[v]) continue; void Dijsktra(int s){
KTH FloydWarshall Kruskal Boruvka DFS 6
return last < n; } int x = nodes[u].back();
} nodes[u].pop_back();
void join(int u, int v) { nodes[v].emplace_back(x);
int main(){ u = comp[u]; comp[x] = v;
edges.emplace_back(make_tuple(u, v, w)); v = comp[v]; }
Bellman(0); if(nodes[u].size() > nodes[v].size()) swap(u, v); }
return 0; while(!nodes[u].empty()) {
} int x = nodes[u].back(); int main() {
nodes[u].pop_back(); scanf("%d %d", &n, &m);
nodes[v].emplace_back(x); for(int i = 0; i < m; i++) {
FloydWarshall.h comp[x] = v; int u, v, w;
Description: Calcula todos los caminos más cortos en un grafo dirigido que } scanf("%d %d %d", &u, &v, &w);
puede tener aristas de peso negativo. La entrada es una matriz n ∗ n donde } G[u].emplace_back(v, w);
indica los pesos
 de las aristas, por otro lado, sino existe tiene valor inf. G[v].emplace_back(u, w);
Time: O N 3 a0559c, 37 lines int get_component(int x) { }
const int N = 1e2 + 5; return comp[x]; init();
const int inf = 2e9 + 10; } int ans = 0;
int n, m; vector<pair<int, int>> mst;
int d[N][N]; int main() { int comps = n;
cin >> n >> m; while(comps > 1) {
int main(){ vector<tuple<int, int, int>> edges; vector<tuple<int, int, int>> L;
cin >> n >> m; for(int i = 0; i < m; i++) { for(int i = 1; i <= n; i++) {
// preprocess int u, v, w; if(nodes[i].empty()) continue;
for(int i = 0; i < n; i++){ cin >> u >> v >> w; int best_cost = INT_MAX;
for(int j = 0; j < n; j++){ edges.push_back({w, u, v}); tuple<int, int, int> light_edge;
d[i][j] = i == j ? 0 : inf; } for(auto u : nodes[i]) {
} sort(edges.begin(), edges.end()); for(auto e : G[u]) {
} init(); int v, w;
// input int ans = 0; tie(v, w) = e;
for(int i = 0; i < m; i++){ vector<pair<int, int>> mst; if(comp[u] == comp[v]) continue;
int u, v, w; for(auto e : edges) { if(w < best_cost) {
cin >> u >> v >> w; int w, u, v; best_cost = w;
d[u][v] = min(d[u][v], w); tie(w, u, v) = e; light_edge = make_tuple(u, v, w);
} if(get_component(u) != get_component(v)) { }
// Floyd warshall ans += w; }
for(int k = 0; k < n; k++){ mst.emplace_back(u, v); }
for(int i = 0; i < n; i++){ join(u, v); L.emplace_back(light_edge);
for(int j = 0; j < n; j++){ } }
if(d[i][k] == inf or d[k][j] == inf) continue; } for(auto e : L) {
if(d[i][j] > d[i][k] + d[k][j]) d[i][j] = d[i][ cout << ans << "\n"; int u, v, w;
k] + d[k][j]; cout << n-1 << "\n"; tie(u, v, w) = e;
} for(auto e : mst) { if(comp[u] == comp[v]) continue;
} cout << e.first << " " << e.second << "\n"; comps -= 1;
} } join(u, v);
// Find negative cycle return 0; ans += w;
for(int i = 0; i < n; i++){ } mst.emplace_back(u, v);
if(d[i][i] < 0){ }
cout << "NEGATIVE CYCLE"; }
return 0; Boruvka.h printf("%d\n", ans);
} Description: Calcula el árbol de expansión minima (MST), usa la opti- printf("%d\n", n - 1);
} mización en rango (DSU). for(auto e : mst) {
return 0; Time: O (E ∗ logE) d6a6f8, 72 lines
printf("%d %d\n", e.first, e.second);
} }
int n, m; return 0;
int comp[N]; }
Kruskal.h vector<pair<int, int>> G[N];
Description: Calcula el árbol de expansión minima (MST), usa la opti- vector<int> nodes[N];
mización en rango (DSU).
5.2 DFS algorithms
Time: O (E ∗ logE) void init() { DFS.h
fbe3d7, 56 lines for(int i = 1; i <= n; i++) { Time: O (|V | + |E|) 706c0e, 36 lines
const int N = 200000 + 5; nodes[i].emplace_back(i);
int n, m; comp[i] = i; #pragma once
int comp[N]; } const int N = 1e5 + 5;
vector<int> nodes[N]; }
int n, m;
void init() { void join(int u, int v) { vector<int> G[N];
for(int i = 1; i <= n; i++) { u = comp[u]; int dis[N];
nodes[i].push_back(i); v = comp[v]; int vis[N];
comp[i] = i; if(nodes[u].size() > nodes[v].size()) swap(u, v); int par[N];
} while(!nodes[u].empty()) {
KTH TopoSortBFS TopoSortDFS SCC Bridges 7
int timer = 1; TopoSortDFS.h dfs(i, 1);
int in[N], out[N]; Description: Ordena los vertices de manera que las arista van de izquierda res.push_back(comp);
a derecha. Si existen ciclos retorna un vector vacio. }
void dfs_visit(int u, int p){ Time: O (|V | + |E|) 4e868b, 30 lines
cout << res.size() << "\n";
vis[u] = 1; for(auto grupo : res){
par[u] = p; bool cycle; cout << grupo.size() << " ";
in[u] = timer++; int vis[N]; for(int x : grupo) {
vector<int> G[N]; cout << x << " ";
for(int v : G[u]){ vector<int> order; }
if(vis[v] == 2) continue; cout << "\n";
else if(vis[v] == 1){ void DFS(int u){ }
// hay un c i c l o en e l grafo , no llamar al d f s v i s i t vis[u] = 1; }
(v) // in [ u ] = timer++;
continue; for(int v : G[u]){ int main(){
} else { if(vis[v] == 2) continue; G[0][u].push_back(v);
dfs_visit(v, u); if(vis[v] == 1) { G[1][v].push_back(u);
} cycle = true; }
} continue;
out[u] = timer++; }
vis[u] = 2; DFS(v);
} } Bridges.h
Description: Encuentra las aristas puente o bridges, es decir, si se elimina
vis[u] = 2; la arista el grafo se divide.
void dfs(){ Time: O (|V | + |E|)
for(int u = 0; u < n; u++){ order.emplace_back(u); b1683e, 45 lines
if(vis[u]) continue; } int n, m;
dfs_visit(u, -1); vector<int> G[N];
} vector<int> topological_sort(){ bool vis[N];
} for(int i = 1; i <= n; i++){
if(vis[i]) continue; int timer;
DFS(i); int in[N];
} int low[N];
if(cycle) order.clear(); vector<pair<int, int>> bridges;
TopoSortBFS.h reverse(order.begin(), order.end());
Description: Ordena los vertices de manera que las arista van de izquierda return order;
a derecha. Si existen ciclos retorna un vector vacio. void dfs(int u, int p){
} vis[u] = 1;
Time: O (|V | + |E|) f91a1e, 33 lines in[u] = timer++;
int n, m; SCC.h low[u] = n+1;
int in[N]; Description: Encuentra las componentes fuertemente conectadas. Cabe for(int v : G[u]){
vector<int> G[N]; resaltar que el algoritmos encuentra los componentes ordenados topologica- if(v == p) continue;
mente. if(vis[v] == 1){
vector<int> toposort(){ Time: O (E + V ) 5dc184, 45 lines low[u] = min(low[u], in[v]);
queue<int> Q; }
vector<int> G[2][N];
vector<int> order; else {
bool vis[N];
dfs(v, u);
stack<int> S;
for(int u = 0; u < n; u++){ low[u] = min(low[u], low[v]);
vector<int> comp;
if(in[u] == 0){ if(low[v] > in[u]){
Q.push(u); if(u < v) bridges.push_back({u, v});
void dfs(int u, int id){
} else bridges.push_back({v, u});
vis[u] = 1;
} }
for(int v : G[id][u]){
while(!Q.empty()){ }
if(vis[v]) continue;
int u = Q.front(); }
dfs(v, id);
Q.pop(); }
}
order.push_back(u); int main(){
if(id == 0) S.push(u);
for(int v : G[u]){ ios_base::sync_with_stdio(0);
else comp.push_back(u);
in[v]--; cin.tie(0);
}
if(in[v] == 0){ cin >> n >> m;
Q.push(v); for(int i = 0; i < m; i++){
void get_scc(){
} int u, v;
for(int i = 0; i < n; i++){
} cin >> u >> v;
if(vis[i]) continue;
} G[u].push_back(v);
dfs(i, 0);
G[v].push_back(u);
}
// deteccion de un c i c l o }
for(int i = 0; i < n; i++) vis[i] = 0;
return order.size() < n ? vector<int>() : order; dfs(0, -1);
} sort(bridges.begin(), bridges.end());
vector<vector<int>> res;
for(auto e : bridges){
while(!S.empty()){
int main(){ cout << e.first << " " << e.second << "\n";
int i = S.top();
// input }
S.pop();
in[v]++; return 0;
comp.clear();
} }
if(vis[i]) continue;
KTH Cutpoints 2sat LCA 8
Cutpoints.h 2sat.h }
Description: Encuentra los nodos o cutpoints, es decir, si se elimina el nodo Description: Calcula una expresión booleana a variabels a, b, c,... de un }
el grafo se divide. 2SAT problem, tal que la expresión es verdadera, o que la expresión no tiene }
Time: O (|V | + |E|) f2124a, 61 lines
solución. vector<int> solve(){
Time: O (N + E), where N is the number of boolean variables, and E is the vector<int> res(n);
const int N = 1e5; number of clauses. get_scc();
5e3f6d, 120 lines
for(int i = 0; i < n; i++){
int n, m; struct SATSolver { int val = 2*i;
vector<int> G[N]; // Assumes that nodes are 0 indexed if(comp[val] == comp[val^1]) return vector<int>();
bool vis[N]; int n, m; if(comp[val] < comp[val^1]) res[i] = 0;
vector<bool> vis; else res[i] = 1;
int timer; vector<int> comp; }
int in[N]; vector<int> order; return res;
int low[N]; vector<int> component; }
vector<vector<int>> G, Gt; };
void is_cutpoint(int u){
cout << u << "\n"; SATSolver(int n, int m) : n(n), m(m){ int main(){
} // x i = 2 i int n, m;
// ∼x i = 2 i+1 cin >> n >> m;
void dfs(int u, int p = -1){ comp.resize(2*n); SATSolver Solver(n, m);
vis[u] = 1; vis.resize(2*n, false); for(int i = 0; i < m; i++){
in[u] = timer++; G.resize(2*n, vector<int>()); // Leemos nodos 1−indexed
low[u] = n + 1; Gt.resize(2*n, vector<int>()); // x i = i
int children = 0; } // ∼x i = −i
int u, v;
for(int v : G[u]){ void add_edge(int u, int v){ cin >> u >> v;
if(v == p) continue; // procesado or ignorar e l padre // u or v if(u < 0){
// (u, v) −> (v , u) G[u^1].push_back(v); u = -u;
if(vis[v] == 1){ G[v^1].push_back(u); u--;
// s i es backedge , aporta a low [u ] Gt[v].push_back(u^1); u = 2*u+1;
low[u] = min(low[u], in[v]); Gt[u].push_back(v^1); }
} } else {
else{ u--;
// aun no procesado ( tree edge) void dfs1(int u){ u = 2*u;
// v e r i f i c a r s i u es cut point vis[u] = 1; }
dfs(v, u); for(int v : G[u]){ if(v < 0){
low[u] = min(low[u], low[v]); if(!vis[v]){ v = -v;
dfs1(v); v--;
// Verificar para nodos diferentes a la raiz } v = 2*v+1;
if(p != -1 and low[v] >= in[u]){ } }
is_cutpoint(u); order.push_back(u); else {
} } v--;
children++; void dfs2(int u){ v = 2*v;
} vis[u] = 1; }
} for(int v : Gt[u]){ Solver.add_edge(u, v);
if(!vis[v]){ }
// Si ’u ’ es raiz , es articulacion s i tiene 2 hijos a mas dfs2(v); vector<int> res = Solver.solve();
if(p == -1 and children > 1) is_cutpoint(u); } if(res.empty()){
} } cout << "There is no solution" << "\n";
component.push_back(u); } else {
void dfs_visit(){ } cout << "One possible solution is: " << "\n";
for(int i = 0; i < n; i++){ void get_scc(){ for(int x : res){
if(vis[i] == 0){ for(int i = 0; i < 2*n; i++){ cout << x << " ";
dfs(i, -1); if(!vis[i]){ }
} dfs1(i); cout << "\n";
} } }
} } return 0;
reverse(order.begin(), order.end()); }
int main(){ fill(vis.begin(), vis.end(), false);
// input
G[u].push_back(v); int id = 0; 5.3 Sparse table tree
G[v].push_back(u); for(int u : order){ LCA.h
if(!vis[u]){ Description: Estructura de datos que calcula el lowest common ancestor en
// process component.clear(); un arbol (raiz en 0). Usa sparse table.
dfs_visit(); dfs2(u); Time: O (N log N + Q)
} for(int x : component){ da2830, 54 lines

comp[x] = id; const int N = 1e4 + 5;


} const int LOG = 14;
id++; int n, q;
int a[N];
KTH Hashing Trie Zfunc 9
int h[N]; }; bool fin[N];
vector<int> G[N]; int cnt[N];
int ST[N][LOG]; ll subhash(11 hashtab[LIM][2], it i, int k, int part, ll mod){
return ((hashtab[i+k-1][part]-hashtab[i-l][part]*pot[k][ void init(){
void compute(int u, int p){ part])%mod+mod)%mod; nodo = 1;
ST[u][0] = p; } for(int i = 0; i < N; i++){
for(int d = 1; 1 << d <= h[u]; d++){ fin[i] = 0;
int y = ST[u][d-1]; int check(int k){ cnt[i] = 0;
ST[u][d] = ST[y][d-1]; if(k==0) return true; for(int j = 0; j < D; j++){
} unordered_set<pair<ll, ll>, hashing_func> sa(n-k+1); trie[i][j] = 0; // nodo no e x i s t e
} for(int i=1; i+k-1<=n; ++i){ }
void dfs(int u, int p = -1){ sa.emplace(subhash(ha, i, k, 0, m0), }
compute(u, p); subhash(ha, i, k, 1, m1)); }
for(int v : G[u]){ }
h[v] = h[u] + 1; for(int i=1; i+k-1<=n; ++i){ void addWord(string s){
dfs(v, u); if(sa.count(make_pair(subhash(hb,i,k,0,m0), int cur = 0; // nodo raiz
} subhash(hb,i,k,1,m1)))){ for(char ch : s){
} return i; int c = ch - ’a’;
void go_up(int &a, int d){ } if(!trie[cur][c]){
while(d){ } trie[cur][c] = nodo++;
int k = __builtin_ctz(d); return -1; }
a = ST[a][k]; } cur = trie[cur][c];
d &= d - 1; void chash(char* str, ll hashtab[LIM][2]){ cnt[cur]++;
} hashtab[0][0] = hashtab[0][1] = 0; }
} for(int i=1; i<=n; ++i){ fin[cur] = 1;
int lca(int u, int v){ hashtab[i][0] = (hashtab[i-1][0]*base+(str[i-1]-’A’))% }
if(h[u] < h[v]) swap(u, v); m0;
// h [ u ] >= h [ v ] hashtab[i][1] = (hashtab[i-1][1]*base+(str[i-1]-’A’))% bool isPrefix(string s){
go_up(u, h[u] - h[v]); // Nos movemos h [u ] − h [ v ] aristas m1; int cur = 0;
hacia arriba } for(char ch : s){
if(u == v) return u; } int c = ch - ’a’;
for(int i = 31 - __builtin_clz(h[u]); i >= 0; i--){ int main() { if(!trie[cur][c]) return 0;
if((1 << i) > h[u]) continue; scanf("%d", &n); cur = trie[cur][c];
if(ST[u][i] != ST[v][i]){ scanf("%s%s", a, b); }
u = ST[u][i]; pot[0][0] = pot[0][1] = 1; return 1;
v = ST[v][i]; }
} for(int i=1;i<LIM;++i){
} pot[i][0] = pot[i-1][0]*base%m0; bool isWord(string s){
return ST[u][0]; pot[i][1] = pot[i-1][1]*base%m1; int cur = 0;
} } for(char ch : s){
chash(a, ha); int c = ch - ’a’;
int main(){ chash(b, hb); if(!trie[cur][c]) return 0;
// input cur = trie[cur][c];
G[u].push_back(v); int lo = 0, hi = n; }
// preprocess int pos = 0, len =0; return fin[cur];
dfs(0); while(lo<=hi){ }
// querys int mid = (lo+hi)/2;
while(q--){ int res = check(mid);
lca(u, v); if(res>=0){ Zfunc.h 680adb, 45 lines
} pos = res-1;
} len = mid; const int MAXPATLEN = 30 + 5;
lo = mid+1; const int MAXTEXLEN = 100000 + 5;
} else {
int z[MAXPATLEN + MAXTEXLEN + 5];
Strings (6) }
hi = mid-1;

} void Z(string &s){


Hashing.h b[pos+len]=0; int n = s.size();
c1a601, 67 lines int L = 0, R = 0;
printf("%s\n", b+pos);
ll m0 = 1e9+7, m1=1e9+9; } for(int i = 0; i < n; i++){
ll base = 37; if(i > R){
const int LIM = 1e5+5; L = R = i;
int n; Trie.h while(R < n && s[R-L] == s[R]) R++;
char a[LIM]; Description: Estructura Trie natural. z[i] = R - L;
char b[LIM]; Time: O (N ∗ D) R--;
ll ha [LIM][2], hb[LIM][2], pot[LIM][2]; 248775, 51 lines } else {
const int N = 1e5 + 1; // Number ∗ s i z e of words int k = i - L;
struct hashingiunc { const int D = 26; if(z[k] < R-i+1) z[i] = z[k];
size_t operator()(const pair<11,11>& x) coast { return x. else {
first;// t h i s i s good enough int nodo; L = i;
} int trie[N][D]; while(R < n && s[R - L] == s[R]) R++;
KTH Snim TimeTakeStones Mergesort 10
z[i] = R - L; } else {
R--; ans ^= grundy(heap, S);
} }
} }
} cout << (ans == 0 ? ’L’ : ’W’);
} }
cout << "\n";
int main(){ }
string text, pat;
cin >> text >> pat; TimeTakeStones.h
string concat = pat + "$" + text; Description: Juego de nim con movimientos especificos (moves).
Z(concat); Time: O (N ) 992983, 14 lines

int cnt = 0; const int N = 1e4 + 5;


int at = pat.size() + 1;
while(at < concat.size()){ vector<int> moves;
if(z[at] == pat.size()){ vector<int> dp(N, 0);
cnt++;
at += pat.size() - 1; bool isWinning(int n){
} dp[0] = 1;
at++; for(int i = 1; i <= n; i++){
} for(int x : moves){
cout << cnt << "\n"; if(n - x >= 0 and !dp[n-x]) dp[n] = 1;
return 0; }
} }
return dp[n];
}
Game theory (7)
Snim.h
Various (8)
Description: Suma de juegos con grundy. Mergesort.h
Time: O (?) cfcf1e, 44 lines Description: Merge Sort 9e3507, 22 lines
int grundy(int n, vector<int> moves){ vector<int> merge(vector<int> &L, vector<int> &R) {
if(n == 0) return 0; vector<int> res;
vector<bool> used(100); int at = 0;
for(int i = 0; i < moves.size(); i++){ for(auto x : L) {
int x = moves[i]; while(at < R.size() and R[at] < x) res.emplace_back(R[at
if(n - x >= 0){ ++]);
used[grundy(n - x, moves)] = 1; res.emplace_back(x);
} }
} while(at < R.size()) res.emplace_back(R[at++]);
int ret = 0; return res;
for(int i = 0; i < 1e4 + 5; i++){ }
if(!used[i]) {
ret = i; vector<int> merge_sort(vector<int> &a) {
break; if(a.size() <= 1) return a;
} int n = a.size();
} int mid = n/2;
return ret; vector<int> L(a.begin(), a.begin() + mid);
} vector<int> R(a.begin() + mid, a.end());

void solve(int k){ L = merge_sort(L);


vector<int> S(k); R = merge_sort(R);
for(int i = 0; i < k; i++){ return merge(L, R);
cin >> S[i]; }
}

int m;
cin >> m;
while(m--){
int l;
cin >> l;
int ans;
for(int i = 0; i < l; i++){
int heap;
cin >> heap;
if(i == 0){
ans = grundy(heap, S);
KTH techniques 11

Techniques (A) Computation of binomial coefficients


Pigeon-hole principle
Knuth-Morris-Pratt
Tries
Inclusion/exclusion Rolling polynomial hashes
techniques.txt 159 lines
Catalan number Suffix array
Pick’s theorem Suffix tree
Recursion Number theory Aho-Corasick
Divide and conquer Integer parts Manacher’s algorithm
Finding interesting points in N log N Divisibility Letter position lists
Algorithm analysis Euclidean algorithm Combinatorial search
Master theorem Modular arithmetic Meet in the middle
Amortized time complexity
Greedy algorithm * Modular multiplication Brute-force with pruning
Scheduling * Modular inverses Best-first (A*)
Max contiguous subvector sum * Modular exponentiation by squaring Bidirectional search
Chinese remainder theorem Iterative deepening DFS / A*
Invariants Fermat’s little theorem Data structures
Huffman encoding Euler’s theorem LCA (2^k-jumps in trees in general)
Graph theory Phi function Pull/push-technique on trees
Dynamic graphs (extra book-keeping) Frobenius number Heavy-light decomposition
Breadth first search Quadratic reciprocity Centroid decomposition
Depth first search Pollard-Rho Lazy propagation
* Normal trees / DFS trees Miller-Rabin Self-balancing trees
Dijkstra’s algorithm Hensel lifting Convex hull trick (wcipeg.com/wiki/Convex_hull_trick)
MST: Prim’s algorithm Vieta root jumping Monotone queues / monotone stacks / sliding queues
Bellman-Ford Game theory Sliding queue using 2 stacks
Konig’s theorem and vertex cover Combinatorial games Persistent segment tree
Min-cost max flow Game trees
Lovasz toggle Mini-max
Matrix tree theorem Nim
Maximal matching, general graphs Games on graphs
Hopcroft-Karp Games on graphs with loops
Hall’s marriage theorem Grundy numbers
Graphical sequences Bipartite games without repetition
Floyd-Warshall General games without repetition
Euler cycles Alpha-beta pruning
Flow networks Probability theory
* Augmenting paths Optimization
* Edmonds-Karp Binary search
Bipartite matching Ternary search
Min. path cover Unimodality and convex functions
Topological sorting Binary search on derivative
Strongly connected components Numerical methods
2-SAT Numeric integration
Cut vertices, cut-edges and biconnected components Newton’s method
Edge coloring Root-finding with binary/ternary search
* Trees Golden section search
Vertex coloring Matrices
* Bipartite graphs (=> trees) Gaussian elimination
* 3^n (special case of set cover) Exponentiation by squaring
Diameter and centroid Sorting
K’th shortest path Radix sort
Shortest cycle Geometry
Dynamic programming Coordinates and vectors
Knapsack
Coin change * Cross product
Longest common subsequence * Scalar product
Convex hull
Longest increasing subsequence Polygon cut
Number of paths in a dag Closest pair
Shortest path in a dag Coordinate-compression
Dynprog over intervals Quadtrees
Dynprog over subsets KD-trees
Dynprog over probabilities All segment-segment intersection
Dynprog over trees Sweeping
3^n set cover Discretization (convert to events and sweep)
Divide and conquer Angle sweeping
Knuth optimization Line sweeping
Convex hull optimizations Discrete second derivatives
RMQ (sparse table a.k.a 2^k-jumps) Strings
Bitonic cycle Longest common substring
Log partitioning (loop over most restricted) Palindrome subsequences
Combinatorics

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy