diff --git a/caderno.pdf b/caderno.pdf index 287710b2c0adc994f9a51831cf88226b60a60b5e..c4990fc0b23c71cafc96aa03b9ea33e086bb1a1d 100644 Binary files a/caderno.pdf and b/caderno.pdf differ diff --git a/caderno/caderno.tex b/caderno/caderno.tex index 85692c16f6e31d86732138e813e90d332c3fa721..15ef3e5738d36e861ac594c7898c57f558f9afb8 100644 --- a/caderno/caderno.tex +++ b/caderno/caderno.tex @@ -26,7 +26,9 @@ \definecolor{commentgreen}{RGB}{2,112,10} \definecolor{eminence}{RGB}{210,31,60} +\DeclareMathOperator{\lcm}{lcm} \newcommand{\bigO}{\mathcal{O}} +\newcommand{\compl}[1]{ \color{commentgreen}{$\bigO(#1)$} } \lstset{ basicstyle=\footnotesize\ttfamily, showspaces=false, @@ -213,7 +215,7 @@ $m, n \in \mathbb{N}$ e $m > n$ de tal forma que: \begin{itemize} \item Se $G$ tem $k$ componentes conectadas, então $n - m + f = k + 1$. \item $m \le 3n - 6$. Se $G$ não tem triângulos, $m \le 2n - 4$. - \item O grau mínimo é $\le 5$. E pode ser 6-colorido em $\mathcal{O}(n+m)$. + \item O grau mínimo é $\le 5$. E pode ser 6-colorido em $\bigO(n+m)$. \end{itemize} \subsection{Corte mínimo} @@ -356,7 +358,7 @@ para $a$ e $m$ coprimos. \lstinputlisting{fontes-com-hash/template.cpp} \subsection{Teste de estresse} \lstinputlisting[language=bash]{fontes-com-hash/stress.sh} -\subsection{Hash de linhas em $[l, r]$} +\subsection{Hash da entrada padrão} \lstinputlisting[language=bash]{fontes-com-hash/hash.sh} \subsection{vimrc} \lstinputlisting{fontes-com-hash/vimrc} @@ -368,46 +370,12 @@ para $a$ e $m$ coprimos. \lstinputlisting{fontes-com-hash/disjoint.h} \subsection{Árvore de Fenwick} -\begin{tabular}{l|l|l} - \hline - 1-indexada & - Atualização $\bigO(\lg n)$ & - Consulta $\bigO(\lg n)$ \\ - \hline -\end{tabular} - -\vspace{4pt} -\noindent -\begin{tabular}{lll} - \hline - \textbf{Atualização} & \textbf{Consulta} & \textbf{Funções} \\ \hline - Ponto & Intervalo & \texttt{add} + \texttt{sum\_inclusive} \\ - Intervalo & Ponto & \texttt{add\_inclusive} + \texttt{pref} \\ - \hline -\end{tabular} - \lstinputlisting{fontes-com-hash/fenwick-tree.h} \subsection{Árvore de Fenwick 2D} -\begin{tabular}{l|l|l} - \hline - 1-indexada & - Atualização $\bigO(\lg^2 n)$ & - Consulta $\bigO(\lg^2 n)$ \\ - \hline -\end{tabular} - \lstinputlisting{fontes-com-hash/fenwick-2d-tree.h} \subsection{Árvore de Fenwick intervalar} -\begin{tabular}{l|l|l} - \hline - 1-indexada & - Atualização $\bigO(\lg n)$ & - Consulta $\bigO(\lg n)$ \\ - \hline -\end{tabular} - \lstinputlisting{fontes-com-hash/fenwick-range-tree.h} \subsection{Tabela esparsa} @@ -424,7 +392,7 @@ para $a$ e $m$ coprimos. \subsection{Árvore de segmentos iterativa} \vspace{4pt} -\noindent +\begin{center} \footnotesize \begin{tabular}{cccc} \hline @@ -434,35 +402,35 @@ para $a$ e $m$ coprimos. \texttt{FACTOR} & \texttt{(tb - ta + 1)} & \texttt{1} & \texttt{1} \\ \hline \end{tabular} +\end{center} \lstinputlisting{fontes-com-hash/segment-tree.h} \subsection{Árvore de segmentos preguiçosa iter.} \lstinputlisting{fontes-com-hash/lazy-segment-tree.h} -\subsection{Nó de Kadane} -\lstinputlisting{fontes-com-hash/kadane.h} +\subsection{K maiores elementos} +\lstinputlisting{fontes-com-hash/k-elements.h} \subsection{Hash customizado} \lstinputlisting{fontes-com-hash/custom-hash.h} -\subsection{Árvore de segmentos recursiva} -\lstinputlisting{fontes-com-hash/recursive-segment-tree.h} +\subsection{Conjunto de intervalos coloridos} +\lstinputlisting{fontes-com-hash/interval-set.h} \subsection{Árvore de segmentos preguiçosa rec.} \lstinputlisting{fontes-com-hash/recursive-lazy-segment-tree.h} -\subsection{Conjunto de intervalos coloridos} -\lstinputlisting{fontes-com-hash/interval-set.h} +\subsection{Árvore de segmentos recursiva} +\lstinputlisting{fontes-com-hash/recursive-segment-tree.h} -\subsection{K maiores elementos} -\lstinputlisting{fontes-com-hash/k-elements.h} +\subsection{Nó de Kadane} +\lstinputlisting{fontes-com-hash/kadane.h} \section{Grafos} \subsection{Articulações e pontes} \lstinputlisting{fontes-com-hash/articulations-bridges.h} -\clearpage \subsection{Componentes fortes -- Tarjan} \lstinputlisting{fontes-com-hash/tarjan.h} @@ -475,31 +443,6 @@ para $a$ e $m$ coprimos. \subsection{Busca em largura 0-1} \lstinputlisting{fontes-com-hash/bfs-01.h} -\subsection{Emparelhamento estável} -\begin{tabular}{l} - \hline - $\bigO(n^2)$ \\ - \hline -\end{tabular} -\lstinputlisting{fontes-com-hash/stable-matching.h} - -\subsection{Caminho euleriano} -\lstinputlisting{fontes-com-hash/eulerian-path.h} - -\clearpage - -\subsection{Stoer-Wagner} -\lstinputlisting{fontes-com-hash/stoer-wagner.h} - -\subsection{Menor no maior} -\lstinputlisting{fontes-com-hash/small-to-large.h} - -\subsection{Árvore geradora mínima -- Prim} -\lstinputlisting{fontes-com-hash/prim.h} - -\subsection{Árvore geradora mínima -- Kruskal} -\lstinputlisting{fontes-com-hash/kruskal.h} - \subsection{Caminho mínimo -- Dijkstra} \lstinputlisting{fontes-com-hash/dijkstra.h} @@ -512,6 +455,15 @@ para $a$ e $m$ coprimos. \subsection{Caminhos mínimos -- Floyd-Warshall} \lstinputlisting{fontes-com-hash/floyd-warshall.h} +\subsection{Árvore geradora mínima -- Kruskal} +\lstinputlisting{fontes-com-hash/kruskal.h} + +\subsection{Árvore geradora mínima -- Prim} +\lstinputlisting{fontes-com-hash/prim.h} + +\subsection{Menor no maior} +\lstinputlisting{fontes-com-hash/small-to-large.h} + \subsection{Fluxo máximo} \lstinputlisting{fontes-com-hash/ford-fulkerson-edmons-karp.h} @@ -521,55 +473,47 @@ para $a$ e $m$ coprimos. \subsection{Fluxo máximo Dinic} \lstinputlisting{fontes-com-hash/dinic.h} -\subsection{Ascensão binária} -\lstinputlisting{fontes-com-hash/binary-lifting.h} - -\subsection{Menor anc. comum -- Ancensão binária} -\lstinputlisting{fontes-com-hash/lca-binary-lifting.h} +\subsection{Stoer-Wagner} +\lstinputlisting{fontes-com-hash/stoer-wagner.h} \subsection{Decomposição pesado-leve} -\begin{tabular}{l|l} - \hline - \multicolumn{2}{l}{ - Precisa de soma de prefixos/árvore de segmentos preguiçosa - } \\ \hline - \multicolumn{2}{l}{ - Se usado com pesos nos vértices, use com $\texttt{edge\_wei} = 0$ - } \\ \hline - Construção $\bigO(|V|\lg|V| + |E|)$ & - Atualização/Consulta $\bigO(\lg^2 n)$ \\ - \hline -\end{tabular} \lstinputlisting{fontes-com-hash/hld.h} \subsection{Decomposição pesado-leve -- K-ésimo} \lstinputlisting{fontes-com-hash/hld-kth.h} -\clearpage +\subsection{Caminho euleriano} +\lstinputlisting{fontes-com-hash/eulerian-path.h} -\subsection{Menor anc. comum -- Offline} -\lstinputlisting{fontes-com-hash/lca-offline.h} +\subsection{Ascensão binária} +\lstinputlisting{fontes-com-hash/binary-lifting.h} -\subsection{Decomposição centróide} -\lstinputlisting{fontes-com-hash/centroid.h} +\subsection{Menor anc. comum -- Ancensão binária} +\lstinputlisting{fontes-com-hash/lca-binary-lifting.h} \subsection{Empar. máximo bipartido -- Kuhn} -\begin{tabular}{l} - \hline - As partes tem enumerações distintas - \\ \hline -\end{tabular} \lstinputlisting{fontes-com-hash/kuhn.h} -\subsection{Emparelhamento Generalizado -- Blossom} +\clearpage + +\subsection{Empar. generalizado -- Blossom} \lstinputlisting{fontes-com-hash/blossom.h} -\subsection{Decomposição raiz quadrada de árvore} -\lstinputlisting{fontes-com-hash/tree-square-root-decomposition.h} +\subsection{Emparelhamento estável} +\lstinputlisting{fontes-com-hash/stable-matching.h} + +\subsection{Decomposição centróide} +\lstinputlisting{fontes-com-hash/centroid.h} \subsection{Menor anc. comum -- Dec. raiz quad.} \lstinputlisting{fontes-com-hash/lca-square-root-decomposition.h} +\subsection{Decomposição raiz quadrada de árvore} +\lstinputlisting{fontes-com-hash/tree-square-root-decomposition.h} + +\subsection{Menor anc. comum -- Offline} +\lstinputlisting{fontes-com-hash/lca-offline.h} + \section{Matemática} \subsection{Operações comuns} @@ -618,19 +562,14 @@ Gera um conjunto $n/i$ para todo $i$ em $\bigO(\sqrt{n})$. \lstinputlisting{fontes-com-hash/division-trick.h} \subsection{Multiplicação -- Karatsuba} -\begin{tabular}{l} - \hline - $\bigO(n^{\log_3 n})$ \\ -\hline -\end{tabular} \lstinputlisting{fontes-com-hash/karatsuba.h} -\subsection{Compressão de coordenadas} -\lstinputlisting{fontes-com-hash/coordinate-compression.h} - \subsection{Inclusão-Exclusão} \lstinputlisting{fontes-com-hash/inclusion-exclusion.h} +\subsection{Compressão de coordenadas} +\lstinputlisting{fontes-com-hash/coordinate-compression.h} + \subsection{Mínimo excluído com conjunto} \lstinputlisting{fontes-com-hash/mexset.h} @@ -644,11 +583,6 @@ Gera um conjunto $n/i$ para todo $i$ em $\bigO(\sqrt{n})$. \lstinputlisting{fontes-com-hash/nim.h} \subsection{Euclides estendido/inv. multiplicativo} -\begin{tabular}{l} - \hline -$\bigO(\lg \min(a, b))$ \\ -\hline -\end{tabular} \begin{align*} ax + by &= \gcd(a, b) \\ ax &= gcd(a, b) \pmod{b} \\ @@ -669,27 +603,12 @@ ax + by = c \lstinputlisting{fontes-com-hash/diophantine.h} \subsection{Fatoração por tentativa} -\begin{tabular}{l} - \hline - $\bigO(\sqrt{n})$ \\ -\hline -\end{tabular} \lstinputlisting{fontes-com-hash/factorize.h} \subsection{Crivo de Eratóstenes} -\begin{tabular}{l} - \hline - $\bigO(n \lg\lg n)$ \\ -\hline -\end{tabular} \lstinputlisting{fontes-com-hash/sieve.h} \subsection{Totiente de Euler} -\begin{tabular}{l} - \hline - $\bigO(n \lg \lg n)$ \\ -\hline -\end{tabular} \lstinputlisting{fontes-com-hash/euler-totient.h} \subsection{Eliminação gaussiana} @@ -702,39 +621,17 @@ ax + by = c \lstinputlisting{fontes-com-hash/miller-rabin.h} \subsection{Pollard Rho} -\begin{tabular}{l} - \hline - $\bigO(n^{1/4})$ \\ -\hline -\end{tabular} \lstinputlisting{fontes-com-hash/pollard-rho.h} \subsection{Teorema chinês do resto} -\begin{tabular}{l} - \hline - $\bigO(t \lg(m_1 m_2 \ldots m_t))$ \\ -\hline -\end{tabular} \lstinputlisting{fontes-com-hash/chinese-remainder-theorem.h} \subsection{Teorema chinês do resto generalizado} -\begin{tabular}{l|l} - \hline - $\bigO(t \lg(m_1 m_2 \ldots m_t))$ & - Infinitas soluções $\pm \text{lcm}(m_1m_2\ldots m_t)$ - \\ \hline -\end{tabular} \lstinputlisting{fontes-com-hash/generalized-chinese-remainder-theorem.h} \section{Strings} \subsection{KMP} -\begin{tabular}{l|l} - \hline - Pré-computação $\bigO(m)$ & - Busca $\bigO(n + m)$ \\ - \hline -\end{tabular} \lstinputlisting{fontes-com-hash/kmp.h} \subsection{Algoritmo Z} @@ -769,19 +666,9 @@ $z[i]$ é o tamanho da maior string que é ao mesmo tempo, um prefixo de $s$ e u \lstinputlisting{fontes-com-hash/point.h} \subsection{Fecho convexo de Graham} -\begin{tabular}{l} - \hline - $\bigO(n \lg n)$ \\ - \hline -\end{tabular} \lstinputlisting{fontes-com-hash/graham.h} \subsection{Fecho convexo com corrente monotônica} -\begin{tabular}{l} - \hline - $\bigO(n \lg n)$ \\ - \hline -\end{tabular} \lstinputlisting{fontes-com-hash/monotone.h} \subsection{Medidor giratório} @@ -866,8 +753,6 @@ Para mudar para superconjunto, use \texttt{\~{}mask} no if. \subsection{Frequência de frequências/moda com Mo} \lstinputlisting{fontes-com-hash/freq-freq-mode.h} -\clearpage - \subsection{Rainhas no tabuleiro} \lstinputlisting{fontes-com-hash/queens.h} diff --git a/fontes/articulations-bridges.h b/fontes/articulations-bridges.h index 472c3ca1da8f914a68bb8289696d8d50fb8a3fd8..188ec5b7d8c61a5a0cc149b531a83795da1b9c60 100644 --- a/fontes/articulations-bridges.h +++ b/fontes/articulations-bridges.h @@ -1,7 +1,7 @@ int tk = 1; vector<int> tin (N, -1), low (N); vector<ii> brid; set<int> arti; -void dfs(int u, int p) { +void dfs(int u, int p) { //<@\compl{n+m}@> tin[u] = low[u] = tk++; int ch = 0; for (auto v : g[u]) { if (v == p) continue; diff --git a/fontes/bellman-ford.h b/fontes/bellman-ford.h index 07b0cb1af47a6fad8802faf678841ff40d909183..7474f1cf19741958fcec1d221de77eab0d82604d 100644 --- a/fontes/bellman-ford.h +++ b/fontes/bellman-ford.h @@ -2,7 +2,7 @@ struct edge { int u, v, w; }; vector<edge> edges; vector<int> d (N, oo); -int bellman_ford(int src, int dest, int n) { +int bellman_ford(int src, int dest, int n) { //<@\compl{nm}@> d[src] = 0; for (int i = 0; i < n - 1; i++) for (auto e : edges) diff --git a/fontes/bfs-01.h b/fontes/bfs-01.h index d8a12b0d8aa5baa3d06dfa29fb8960a297f19758..2b856bcaaf0d74468e1e5c278634c52ab1f58c6b 100644 --- a/fontes/bfs-01.h +++ b/fontes/bfs-01.h @@ -1,12 +1,9 @@ vector<int> d (N, oo); -void bfs01(int s) { - d[s] = 0; - deque<int> q; - q.push_front(s); +void bfs01(int s) { //<@\compl{n+m}@> + d[s] = 0; deque<int> q; q.push_front(s); while (!q.empty()) { - int u = q.front(); - q.pop_front(); + int u = q.front(); q.pop_front(); for (auto [v, w] : g[u]) if (d[u] + w < d[v]) { d[v] = d[u] + w; if (w == 1) { q.push_back(v); } diff --git a/fontes/binary-lifting.h b/fontes/binary-lifting.h index 8818dd1ef0f3518973071ae01092b10870211f59..1d03e8461bec68e738e6713bfdd027e165d0301d 100644 --- a/fontes/binary-lifting.h +++ b/fontes/binary-lifting.h @@ -10,7 +10,7 @@ void bl_euler_tour(int u, int p, int w) { bl_euler_tour(v, u, w); } -void bl_init(int u, int n) { +void bl_init(int u, int n) { //<@\compl{m + n\lg n}@> dep[u] = -1; bl_euler_tour(u, u, 0); // can be put into bl_euler_tour but it will not // work with cycles (could be useful for online) @@ -22,7 +22,7 @@ void bl_init(int u, int n) { } } -ll bl_op(int a, int b) { +ll bl_op(int a, int b) { //<@\compl{\lg n}@> if (!(dep[a] > dep[b])) { swap(a, b); } ll res = NEUTRAL; int diff = dep[a] - dep[b]; diff --git a/fontes/binomial-distribution.h b/fontes/binomial-distribution.h index 5f73423c80f99899bb43153f2f32cbcef6ae03d9..48d3d8b9a70e7d871d34860e6ff31d38793384e0 100644 --- a/fontes/binomial-distribution.h +++ b/fontes/binomial-distribution.h @@ -1,8 +1,7 @@ vector<double> logfact (N); - void calc() { for (int i = 1; i < N; i++) - logfact[i] = logfact [i-1] + log(i); + logfact[i] = logfact[i-1] + log(i); } double binom (int n, int k, double p) { diff --git a/fontes/blossom.h b/fontes/blossom.h index e835c48ff96dda9b6772a48a8215f77348015798..4ab6ab71f8f5d7c5707c46889e2936c83056f2fd 100644 --- a/fontes/blossom.h +++ b/fontes/blossom.h @@ -1,16 +1,14 @@ -int n; vector<int> match (N), par (N), base (N), vis (N); -queue<int> q; +int n; queue<int> q; void contract(int u, int v, bool first = 1) { static vector<bool> bloss; static int l; if (first) { bloss = vector<bool>(n, 0); - vector<bool> ok (n, 0); - int k = u; l = v; + vector<bool> ok (n, 0); int k = u; l = v; while (1) { ok[k = base[k]] = 1; - if (match[k] == -1) break; + if (match[k] == -1) { break; } k = par[match[k]]; } while (!ok[l = base[l]]) l = par[match[l]]; @@ -23,19 +21,20 @@ void contract(int u, int v, bool first = 1) { contract(v, u, 0); for (int u = 0; u < n; u++) if (bloss[base[u]]) { base[u] = l; - if (!vis[u]) { q.push(u); } - vis[u] = 1; + if (!vis[u]) { q.push(u); } vis[u] = 1; } } int getpath(int s) { - for (int i = 0; i < n; i++) base[i] = i, par[i] = -1, vis[i] = 0; + for (int i = 0; i < n; i++) + base[i] = i, par[i] = -1, vis[i] = 0; vis[s] = 1; q = queue<int>(); q.push(s); while (q.size()) { int u = q.front(); q.pop(); for (int i : g[u]) { - if (base[i] == base[u] || match[u] == i) { continue; } - if (i == s or (match[i] != -1 && par[match[i]] != -1)) + if (base[i] == base[u] || match[u] == i) + continue; + if (i == s || (~match[i] && ~par[match[i]])) contract(u, i); else if (par[i] == -1) { par[i] = u; @@ -48,13 +47,11 @@ int getpath(int s) { return -1; } -int blossom() { - int ans = 0; - fill(all(match), -1); +int blossom() { //<@\compl{n^3}@> + int ans = 0; fill(all(match), -1); for (int i = 0; i < n; i++) if (match[i] == -1) for (int j : g[i]) if (match[j] == -1) { - match[i] = j; match[j] = i; ans++; break; - } + match[i] = j; match[j] = i; ans++; break; } for (int i = 0; i < n; i++) if (match[i] == -1) { int j = getpath(i); if (j == -1) { continue; } ans++; diff --git a/fontes/bruijn.h b/fontes/bruijn.h index 5d09f534bfe9ac43c1f5c07080d412cbaeaae938..4560f0bc71bd8f3c920384428d84cef927cc77c4 100644 --- a/fontes/bruijn.h +++ b/fontes/bruijn.h @@ -1,5 +1,4 @@ -vector<int> a (K*N, 0); -vector<int> seq; +vector<int> a (K*N, 0), seq; void de_bruijn(int k, int n, int t=1, int p=1) { if (t > n && n % p == 0) diff --git a/fontes/centroid.h b/fontes/centroid.h index 837de3e71496ed6c317f641ce8550824c4b80170..bbf0b14f61dbc7d06cd65d14caf2c4f700700cea 100644 --- a/fontes/centroid.h +++ b/fontes/centroid.h @@ -14,10 +14,10 @@ int find_centroid(int u, int p, int n) { return u; } -void centroid_decompose(int u, int p, int d = 0) { +void centroid_decomp(int u, int p, int d=0) { //<@\compl{n+m}@> calc_size(u, u); int c = find_centroid(u, u, sz[u]); vis[c] = 1; parc[c] = p; for (int v : g[c]) if (!vis[v]) - centroid_decompose(v, c, d+1); + centroid_decomp(v, c, d+1); } diff --git a/fontes/chinese-remainder-theorem.h b/fontes/chinese-remainder-theorem.h index 958010d3356644fc6a5f5f7f6baee028ed5772df..801c79a265253d56ab2b30c6c7c717e81b422437 100644 --- a/fontes/chinese-remainder-theorem.h +++ b/fontes/chinese-remainder-theorem.h @@ -1,3 +1,5 @@ +// infinite solutions <@$\pm \lcm(m_1m_2\ldots m_t)$@> +//<@\compl{t \lg m_1m_2\ldots m_t}@> ll crt(vector<ll> a, vector<ll> m, int t) { ll p = 1; for (ll& mi : m) { p *= mi; } ll ans = 0; diff --git a/fontes/custom-hash.h b/fontes/custom-hash.h index e80c99aa5a203869bdbc0f649abb0bf1519d7742..a238efdb3a9adb9a0b8912ee2487b3d2c2ca39fe 100644 --- a/fontes/custom-hash.h +++ b/fontes/custom-hash.h @@ -1,16 +1,11 @@ struct custom_hash { - static uint64_t splitmix64(uint64_t x) { - // http://xorshift.di.unimi.it/splitmix64.c - x += 0x9e3779b97f4a7c15; - x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; - x = (x ^ (x >> 27)) * 0x94d049bb133111eb; - return x ^ (x >> 31); - } - - size_t operator()(uint64_t x) const { + size_t operator()(uint64_t x) const { //<@\compl{1}@> static const uint64_t FIXED_RANDOM = chrono::steady_clock::now() .time_since_epoch().count(); - return splitmix64(x + FIXED_RANDOM); + x += FIXED_RANDOM + 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); } }; diff --git a/fontes/dijkstra.h b/fontes/dijkstra.h index 2a757a9becd674585f06ee326e1b3370e2263587..a198417e7b09f0244e037578ec1bec758376781a 100644 --- a/fontes/dijkstra.h +++ b/fontes/dijkstra.h @@ -1,15 +1,14 @@ -void dijkstra(int src, int dest, int n) { +void dijkstra(int s, int t, int n) { //<@\compl{(m + n)\lg n}@> vector<ll> d (n, oo); vector<bool> vis (n); vector<vector<int>> dag (n); priority_queue<ii, vector<ii>, greater<ii>> q; - d[src] = 0; q.push({0, src}); + d[s] = 0; q.push({0, s}); while (!q.empty()) { auto [c, u] = q.top(); q.pop(); - if (vis[u]) { continue; } - vis[u] = 1; + if (vis[u]) { continue; } vis[u] = 1; for (auto [v, w] : gt[u]) if (d[u] == d[v] + w) dag[v].push_back(u); - if (u == dest) { break; } + if (u == t) { break; } for (auto [v, w] : g[u]) if (d[v] > d[u] + w) { d[v] = d[u] + w; diff --git a/fontes/dinic.h b/fontes/dinic.h index 00a90e7f52934b6bf6901202fa18789e6c5e946d..5b01160537bcf01dd9c7febd69e0a1c9d74d0a94 100644 --- a/fontes/dinic.h +++ b/fontes/dinic.h @@ -32,11 +32,10 @@ ll dfs(int u, int t, ll pushed) { return 0; } -ll dinic /* O(EV^2) */(int s, int t) { +ll dinic(int s, int t) { //<@\compl{mn^2}@> ll max_flow = 0; while (1) { - fill(all(level), -1); - level[s] = 0; q.push(s); + fill(all(level), -1); level[s] = 0; q.push(s); if (!minimum_path(s, t)) { break; } fill(all(ptr), 0); while (ll pushed = dfs(s, t, 1e18)) diff --git a/fontes/disjoint.h b/fontes/disjoint.h index fda3eb40ae7a2f150153aa28a6f4ebb8beb9996a..3154000f392ffa2338d4d37204790de83bcd935a 100644 --- a/fontes/disjoint.h +++ b/fontes/disjoint.h @@ -1,11 +1,11 @@ vector<int> rep (N), rnk (N), siz (N); -int ds_find(int u) { +int ds_find(int u) { //<@\compl{\alpha(n)}@> if (rep[u] != u) { rep[u] = ds_find(rep[u]); } return rep[u]; } -void ds_unite(int u, int v) { +void ds_unite(int u, int v) { //<@\compl{\alpha(n)}@> u = ds_find(u); v = ds_find(v); assert(u != v); if (!(rnk[u] > rnk[v])) { swap(u, v); } @@ -14,8 +14,7 @@ void ds_unite(int u, int v) { siz[u] += siz[v]; } -void ds_init(int n) { - for (int u = 0; u < n; u++) { - rep[u] = u; rnk[u] = 0; siz[u] = 1; - } +void ds_init(int n) { //<@\compl{n}@> + for (int u = 0; u < n; u++) + rep[u] = u, rnk[u] = 0, siz[u] = 1; } diff --git a/fontes/euler-totient.h b/fontes/euler-totient.h index 856870aeaa7be9e4506cb27e4844b41bec677874..7ea7cbe5ca69c853b116e70dd259619cff875d62 100644 --- a/fontes/euler-totient.h +++ b/fontes/euler-totient.h @@ -1,5 +1,5 @@ vector<ll> phi (N); -void totient(int n) { +void totient(int n) { //<@\compl{n \lg n}@> for (int i = 1; i <= n; i++) { phi[i] = i; } for (int i = 2; i <= n; i++) if (phi[i] == i) { for (int j = i; j <= n; j += i) { diff --git a/fontes/eulerian-path.h b/fontes/eulerian-path.h index 9bb3a344d634e450cec9d8c9d565928004d042ca..3b8b6c09023d3a2341f4581d7c06743919501099 100644 --- a/fontes/eulerian-path.h +++ b/fontes/eulerian-path.h @@ -1,13 +1,12 @@ -vector<int> eulerian_path(int src, int n) { +vector<int> eulerian_path(int src, int n) { //<@\compl{n+m}@> for (int u = 0; u < n; u++) if (deg[u] % 2) { return {}; } stack<int> st; st.push(src); - vector<int> res; + vector<int> ans; while (!st.empty()) { int u = st.top(); if (g[u].empty()) { - res.push_back(u); - st.pop(); + ans.push_back(u); st.pop(); } else { int v = *begin(g[u]); g[u].erase(g[u].find(v)); @@ -17,6 +16,6 @@ vector<int> eulerian_path(int src, int n) { } for (int u = 0; u < n; u++) if (g[u].size()) return {}; - reverse(all(res)); - return res; + reverse(all(ans)); + return ans; } diff --git a/fontes/extended-euclidean.h b/fontes/extended-euclidean.h index 61b6a6cb42df1b156e8ae78629a9456bedde2483..6aeb76295a925849c9878cf4418c7591698af49b 100644 --- a/fontes/extended-euclidean.h +++ b/fontes/extended-euclidean.h @@ -1,4 +1,4 @@ -ll extgcd(ll a, ll b, ll& x, ll& y) { +ll extgcd(ll a, ll b, ll& x, ll& y) { //<@\compl{\lg \min(a, b)}@> if (b == 0) { x = 1; y = 0; return a; } ll g = extgcd(b, a%b, x, y); tie(x, y) = make_tuple(y, x - (a/b)*y); diff --git a/fontes/factorize.h b/fontes/factorize.h index 1cf040c3dd97634b32f6b9ced3709f84ec197615..4961dcdcae8d6d3114f5622b83035d4105ba422b 100644 --- a/fontes/factorize.h +++ b/fontes/factorize.h @@ -1,11 +1,8 @@ -vector<int> factorize(ll n) { - vector<int> v; +map<int, int> factorize(ll n) { //<@\compl{\sqrt{n}}@> + map<int, int> v; for (ll i = 2; i*i <= n; i++) - while (n % i == 0) { - n /= i; - v.push_back(i); - } - if (n > 1) - v.push_back(n); + while (n % i == 0) + n /= i, v[i]++; + if (n > 1) { v[n]++; } return v; } diff --git a/fontes/fenwick-2d-tree.h b/fontes/fenwick-2d-tree.h index 044009d1548633d21fc50f78ad7fa5c983d3abdc..ca0a95f5d163e41d7c1b95e4ba8dacead5571e5a 100644 --- a/fontes/fenwick-2d-tree.h +++ b/fontes/fenwick-2d-tree.h @@ -1,12 +1,12 @@ vector<vector<ll>> bit (N, vector<ll>(M)); -void add(int x, int y, ll d) { +void add(int x, int y, ll d) { //<@\compl{\lg^2 n}@> for (; x < N; x += x & -x) for (int j = y; j < M; j += j & -j) bit[x][j] += d; } -ll pref(int x, int y) { +ll pref(int x, int y) { //<@\compl{\lg^2 n}@> ll sum = 0; for (; x > 0; x -= x & -x) for (int j = y; j > 0; j -= j & -j) diff --git a/fontes/fenwick-range-tree.h b/fontes/fenwick-range-tree.h index a8d6142c8b53cb41b81c80bc4f17f85e3993e588..b9df47b63745a2243c17986c0ddc9a0a072edb5d 100644 --- a/fontes/fenwick-range-tree.h +++ b/fontes/fenwick-range-tree.h @@ -1,10 +1,10 @@ vector<ll> bit1 (N), bit2 (N); -void add(vector<ll>& bit, int i, ll d) { +void add(vector<ll>& bit, int i, ll d) { //<@\compl{\lg n}@> for (; i < N; i += i & -i) { bit[i] += d; } } -ll pref(vector<ll>& bit, int i) { +ll pref(vector<ll>& bit, int i) { //<@\compl{\lg n}@> ll sum = 0; for (; i > 0; i -= i & -i) { sum += bit[i]; } return sum; diff --git a/fontes/fenwick-tree.h b/fontes/fenwick-tree.h index 686efc32997d6bbdd07196cf2c79305db4db8987..d4a9915377ef7745aa79a3728d3a4d9438d1b379 100644 --- a/fontes/fenwick-tree.h +++ b/fontes/fenwick-tree.h @@ -1,27 +1,27 @@ vector<ll> bit (N, 0); -void add(int i, ll d) { +void add(int i, ll d) { //<@\compl{\lg n}@> for (; i < N; i += i & -i) { bit[i] += d; } } -ll pref(int i) { +ll pref(int i) { //<@\compl{\lg n}@> ll sum = 0; for (; i > 0; i -= i & -i) { sum += bit[i]; } return sum; } int sum_inclusive(int i, int j) { - return pref(j) - pref(i - 1); + return pref(j) - pref(i-1); } void add_inclusive(int a, int b, ll d) { add(a, d); add(b + 1, -d); } -int lower_bound(ll t) { +int lower_bound(ll t) { //<@\compl{\lg n}@> ll sum = 0; int pos = 0; for (int p = log2(N); p >= 0; p--) if ( - pos + (1 << p) < N && sum + bit[pos + (1 << p)] < t) { + pos + (1<<p) < N && sum + bit[pos + (1<<p)] < t) { sum += bit[pos + (1 << p)]; pos += (1 << p); } diff --git a/fontes/floyd-warshall.h b/fontes/floyd-warshall.h index df7d13beb6196e1fae48f43135d3528c61d67213..33ddf3537766b1b057c33859adc8f89be3750104 100644 --- a/fontes/floyd-warshall.h +++ b/fontes/floyd-warshall.h @@ -1,6 +1,6 @@ vector<vector<ll>> d (N, vector<ll>(N, oo)); -void floydwarshall(int n) { +void floydwarshall(int n) { //<@\compl{n^3}@> for (int u = 0; u < n; u++) d[u][u] = 0; for (int m = 0; m < n; m++) diff --git a/fontes/ford-fulkerson-edmons-karp-min-cost.h b/fontes/ford-fulkerson-edmons-karp-min-cost.h index 97f25d37f22c1e68ebc56b599bc2844b3e204219..de6b718388d374b7ecad3498c8eb7549b4dcfbca 100644 --- a/fontes/ford-fulkerson-edmons-karp-min-cost.h +++ b/fontes/ford-fulkerson-edmons-karp-min-cost.h @@ -1,6 +1,5 @@ struct edge { int u, v, cap, cost; }; vector<edge> edges; - vector<int> queu (N), ix (N), dist (N), par (N); void link(int u, int v, int cap, int cost) { diff --git a/fontes/ford-fulkerson-edmons-karp.h b/fontes/ford-fulkerson-edmons-karp.h index 5def2dedfa683c4709bcc1d5fdd8c2e084f8c448..ee547da42d68a46abe6ec14ba7e41d3f38391af7 100644 --- a/fontes/ford-fulkerson-edmons-karp.h +++ b/fontes/ford-fulkerson-edmons-karp.h @@ -26,13 +26,12 @@ bool minimum_path(int s, int t) { return dist[t] < oo; } -pair<int, int> ffek /* O(VE^2) */(int s, int t) { +pair<int, int> ffek(int s, int t) { //<@\compl{nm^2}@> int min_cost = 0, max_flow = 0; while (minimum_path(s, t)) { int flow = oo; - for (int u = t; u != s; u = par[u]) { + for (int u = t; u != s; u = par[u]) flow = min(flow, edges[ix[u]].cap); - } for (int u = t; u != s; u = par[u]) { edges[ix[u] ].cap -= flow; edges[ix[u]^1].cap += flow; diff --git a/fontes/gauss.h b/fontes/gauss.h index 2abfb8cc4b3161e90bc65998ae98d5b52c07d2b8..329b05246b6148d9e9cf2b36bf0f7e58cc0e0a88 100644 --- a/fontes/gauss.h +++ b/fontes/gauss.h @@ -1,5 +1,5 @@ template<typename T> -pair<int, vector<T>> gauss( +pair<int, vector<T>> gauss( //<@\compl{mn^2}@> vector<vector<T>> a, vector<T> b) { const double eps = 1e-6; int n = a.size(), m = a[0].size(); diff --git a/fontes/generalized-chinese-remainder-theorem.h b/fontes/generalized-chinese-remainder-theorem.h index 6fb5fc518c6c6e0abf85a50993fc87184f17714d..abd721e88d237a529b1510c0d987d5eaa5a77de7 100644 --- a/fontes/generalized-chinese-remainder-theorem.h +++ b/fontes/generalized-chinese-remainder-theorem.h @@ -1,19 +1,19 @@ ll norm(ll a, ll b) { - a %= b; return (a < 0) ? a + b : a; + a %= b; return (a < 0) ? a + b : a; } pair<ll, ll> crt_single(ll a, ll n, ll b, ll m) { - ll x, y; ll g = extgcd(n, m, x, y); - if ((a - b) % g) { return {-1, -1}; } - ll lcm = (m/g) * n; - return {norm(a + n*(x*(b-a)/g % (m/g)), lcm), lcm}; + ll x, y; ll g = extgcd(n, m, x, y); + if ((a - b) % g) { return {-1, -1}; } + ll lcm = (m/g) * n; + return {norm(a + n*(x*(b-a)/g % (m/g)), lcm), lcm}; } ll crt(vector<ll> a, vector<ll> m, int t) { - ll ans = a[0], lcm = m[0]; - for (int i = 1; i < t; ++i) { - tie(ans, lcm) = crt_single(ans, lcm, a[i], m[i]); - if (ans == -1) { return -1; } - } - return ans; + ll ans = a[0], lcm = m[0]; + for (int i = 1; i < t; ++i) { + tie(ans, lcm) = crt_single(ans, lcm, a[i], m[i]); + if (ans == -1) { return -1; } + } + return ans; } diff --git a/fontes/hash.sh b/fontes/hash.sh index 3990611f3f56cf6e70d14c76ccdf78dfd8d87618..6543aa1ad1404f864f9b21eb2231efeeafd5947b 100644 --- a/fontes/hash.sh +++ b/fontes/hash.sh @@ -1,2 +1,7 @@ -sed -n $2','$3' p' $1 | sed '/^#w/d' | cpp -dD -P \ - -fpreprocessed | tr -d '[:space:]' | md5sum | cut -c -3 +while IFS="" read -r l; do + h=$(echo "$l" | sed '/^#w/d' | + cpp -dD -P -fpreprocessed | + tr -d '[:space:]' | md5sum | cut -c -3) + [ -z "$l" ] && h="" + echo "$h $l" +done diff --git a/fontes/hld.h b/fontes/hld.h index 73d19f0532bbfdeb00df81f23a224406cbc23c27..30e79ab00f1504b4588987042984ec903bfa36bb 100644 --- a/fontes/hld.h +++ b/fontes/hld.h @@ -21,7 +21,7 @@ void hld(int u, int h) { hld(v, v); // new chain } -ll hld_op(int u, int v, bool edge_wei = 1) { +ll hld_op(int u, int v, bool edge_wei = 1) { //<@\compl{\lg q}@> ll ans = 0; for (; hds[u] != hds[v]; v = par[hds[v]]) { if (dep[hds[u]] > dep[hds[v]]) { swap(u, v); } @@ -31,6 +31,6 @@ ll hld_op(int u, int v, bool edge_wei = 1) { return OP(ans, op_inclusive(ixs[u] + edge_wei, ixs[v])); } -void hld_init(int u, int n) { +void hld_init(int u, int n) { //<@\compl{n+m+b}@> cix = 1; hld_fill(u, u); hld(u, u); build(ori, n); } diff --git a/fontes/interval-set.h b/fontes/interval-set.h index 818d3a76542afd2c7f82fa7308a898701841ec1f..8db08b75ade7a399065bbbb4b1c2e833a7b42b88 100644 --- a/fontes/interval-set.h +++ b/fontes/interval-set.h @@ -9,7 +9,7 @@ struct itvl { set<itvl, less<>> si; -void ins_in(itvl in) { +void ins_in(itvl in) { //<@\compl{\lg n}@> auto it = si.lower_bound(in); int a = in.a, b = in.b, c = in.c; if (si.size() > 0 && it != begin(si) @@ -23,7 +23,7 @@ void ins_in(itvl in) { si.insert(itvl(a, b, c)); } -void upd_color(int a, int b, int c) { +void upd_color(int a, int b, int c) { //<@\compl{\lg n}@> auto it = si.lower_bound(b); if (it != end(si)) { itvl ori = *it; si.erase(it); diff --git a/fontes/josephus.h b/fontes/josephus.h index 89062e672ccd2b2f083d5291342eb0e918675852..80b00f8c68da71451bf76011735ff88c1c563313 100644 --- a/fontes/josephus.h +++ b/fontes/josephus.h @@ -1,13 +1,13 @@ -int josephusrec(int n, int k) { +int josephusrec(int n, int k) { //<@\compl{n}@> return n ? (josephusrec(n-1, k) + k) % n : 0; } -int josephus /* O(n) */ (int n, int k) { +int josephus(int n, int k) { //<@\compl{n}@> int res = 0; for (int i = 1; i <= n; ++i) res = (res + k) % i; return res+1; } -int josephusklgn /* O(k log n) */ (int n, int k) { +int josephusklgn(int n, int k) { //<@\compl{k\lg n}@> if (n == 1) { return 0; } if (k == 1) { return n-1; } if (k > n) { return (josephusklgn(n-1, k) + k) % n; } diff --git a/fontes/k-elements.h b/fontes/k-elements.h index 043baed7ba8024fe2a0be6eb4ebf6dc876cc7e7b..3ac64dda75660b3bb567284b9b27b38472c7eafd 100644 --- a/fontes/k-elements.h +++ b/fontes/k-elements.h @@ -8,7 +8,7 @@ template <class C = less<>> struct k_elements { int k; ord_set<pair<ll, int>, C> s; ll sum; k_elements(int k) : k(k), sum(0) {}; - void insert(int key, ll value) { + void insert(int key, ll value) { //<@\compl{\lg n}@> int l = s.order_of_key(make_pair(value, key)); s.insert(make_pair(value, key)); if (l >= k) { return; } @@ -16,7 +16,7 @@ struct k_elements { if (s.size() > k) sum -= s.find_by_order(k)->first; } - void remove(int key, ll value) { + void remove(int key, ll value) { //<@\compl{\lg n}@> if (s.order_of_key(make_pair(value, key)) < k) { sum -= value; if (s.size() > k) diff --git a/fontes/kadane.h b/fontes/kadane.h index 76dec7c7df4505528e417d8f92294e13b15cfc14..eb07582aa05a84f2ff0c04c8e100048a1ad34608 100644 --- a/fontes/kadane.h +++ b/fontes/kadane.h @@ -1,13 +1,13 @@ struct kadane { - int sum, pref, suff, ans; - kadane() : sum(-oo) { pref = suff = ans = 0; } - kadane(int x) : sum(x) { pref = suff = ans = max(x, 0); } + int sum, pre, suf, ans; + kadane(int x) : sum(x) { pre = suf = ans = max(x, 0); } + kadane() : kadane(-oo) {} kadane operator+(kadane const& r) { auto l = *this; kadane a; a.sum = max(l.sum + r.sum, -oo); - a.pref = max(l.pref, l.sum + r.pref); - a.suff = max(r.suff, r.sum + l.suff); - a.ans = max({ l.ans, r.ans, l.suff + r.pref }); + a.pre = max(l.pre, l.sum + r.pre); + a.suf = max(r.suf, r.sum + l.suf); + a.ans = max({ l.ans, r.ans, l.suf + r.pre }); return a; } } diff --git a/fontes/karatsuba.h b/fontes/karatsuba.h index b9b60e4cec68f416b707164e48f922a1ea5d672d..48e949adc65e6ee6148d51dc8ebdb849fd5bf726 100644 --- a/fontes/karatsuba.h +++ b/fontes/karatsuba.h @@ -1,5 +1,5 @@ -vector<ll> karatsuba(const vector<ll> &a, - const vector<ll> &b) { +vector<ll> karatsuba /* O(n^{log 3 n})*/( + const vector<ll> &a, const vector<ll> &b) { int n = a.size(); vector<ll> res(n + n); if (n <= 32) { diff --git a/fontes/kosaraju.h b/fontes/kosaraju.h index 1a4d62aed966de20b35cb9f1c7d57f485ae885fe..6f6fe21ea21648efd69545df4afcf34de942809f 100644 --- a/fontes/kosaraju.h +++ b/fontes/kosaraju.h @@ -1,10 +1,8 @@ -int cts = 1; -vector<int> vis (N), rep (N); +int cts = 1; vector<int> vis (N), rep (N); stack<int> sinks; void fill_stack(int u) { - if (vis[u] == cts) { return; } - vis[u] = cts; + if (vis[u] == cts) { return; } vis[u] = cts; for (int v : g_t[u]) { fill_stack(v); } sinks.push(u); } @@ -15,10 +13,9 @@ void mark_component(int u, int r) { for (int v : g[u]) { mark_component(v, r); } } -stack<int> kosaraju(int n) { +stack<int> kosaraju(int n) { //<@\compl{n+m}@> for (int u = 0; u < n; u++) { fill_stack(u); } - cts++; - stack<int> topo; + cts++; stack<int> topo; while (!sinks.empty()) { int u = sinks.top(); sinks.pop(); mark_component(u, u); diff --git a/fontes/kruskal.h b/fontes/kruskal.h index 08633801142cad3f6105fda66c20b29d695231cc..c0f2bddfaae02977e5b28ef341ea7f8eb41e5965 100644 --- a/fontes/kruskal.h +++ b/fontes/kruskal.h @@ -3,7 +3,7 @@ struct edge { bool operator<(struct edge &o) { return w < o.w; } }; -int kruskal(int n) { +int kruskal(int n) { //<@\compl{m\alpha(n)}@> sort(all(edges)); ds_init(n); int components = n; ll sum = 0; for (auto [u, v, w] : edges) { diff --git a/fontes/kuhn.h b/fontes/kuhn.h index 855e504ebb8f30b46d38ccc965db4161161edaac..049c1545d40ffe6ad05e6d722f5ad28651253cd3 100644 --- a/fontes/kuhn.h +++ b/fontes/kuhn.h @@ -1,3 +1,4 @@ +// distinct enumeration vector<vector<int>> g (L); vector<int> matchr (R, -1); @@ -10,7 +11,7 @@ int dfs(int u) { return 0; } -int kuhn(int l) { +int kuhn(int l) { //<@\compl{nm}@> int ans = 0; for (int u = 0; u < l; u++) { ans += dfs(u); cts++; } return ans; diff --git a/fontes/lazy-segment-tree.h b/fontes/lazy-segment-tree.h index 9ad17ad67e963b5a32d27d45eab7468a27280c73..64115a750843cfb923a6f37e4093c8d7a66c0ca0 100644 --- a/fontes/lazy-segment-tree.h +++ b/fontes/lazy-segment-tree.h @@ -2,7 +2,7 @@ const int L = ceil(log2(N)); struct dlta { int add = 0, set = -1; }; vector<ll> t (2*N); vector<dlta> delta (2*N); -void build(vector<int>& src, int n) { +void build(vector<int>& src, int n) { //<@\compl{n}@> for (int i = 1; i <= n; i++) t[n+i] = src[i]; for (int ti = n-1; ti > 0; ti--) @@ -39,7 +39,7 @@ void push(int i) { } void apply_inclusive(int l, int r, int n, - char op = '\0', ll x = 0) { + char op = '\0', ll x = 0) { //<@\compl{\lg n}@> r++; dlta d; if (op == '+') { d.add = x; } if (op == '=') { d.set = x; } @@ -56,7 +56,7 @@ void add_inclusive(int l, int r, int n, ll d) { apply_inclusive(l, r, n, '+', d); } -ll op_inclusive(int l, int r, int n) { +ll op_inclusive(int l, int r, int n) { //<@\compl{\lg n}@> r++; int tl = l += n, tr = r += n, sz = 1; push(tl); push(tr); diff --git a/fontes/lca-offline.h b/fontes/lca-offline.h index 8a87143ff8eff866426dc399316d9973ccb373da..125513909b6c4549ed8684d218d45aebd5150956 100644 --- a/fontes/lca-offline.h +++ b/fontes/lca-offline.h @@ -1,7 +1,7 @@ vector<vector<int>> queries (N); vector<int> anc (N); vector<bool> vis (N); -void dfs(int u) { +void dfs(int u) { //<@\compl{n\alpha(n)+m+q\alpha(n)}@> vis[u] = 1; anc[u] = u; for (int v : adj[u]) if (!vis[v]) { dfs(v); ds_unite(u, v); anc[ds_find(u)] = u; diff --git a/fontes/min-queue.h b/fontes/min-queue.h index 1c0fd81e5c21023657cca97939dca3d5087c4f2a..99f1f504d4cec8fe5d59084b869f2c27b1b404ff 100644 --- a/fontes/min-queue.h +++ b/fontes/min-queue.h @@ -1,10 +1,10 @@ stack<pair<int, int>> s1, s2; -void enqueue_el(int x) { +void enqueue_el(int x) { //<@\compl{1}@> int m = min(x, s1.size() ? s1.top().second : oo); s1.push({ x, m }); } -int dequeue_el() { +int dequeue_el() { //<@\compl{1}@> if (s2.empty()) while (!s1.empty()) { int el = s1.top().first; s1.pop(); int m = min(el, s2.size() ? s2.top().second : oo); @@ -12,7 +12,7 @@ int dequeue_el() { } int r = s2.top().first; s2.pop(); return r; } -int min_el() { +int min_el() { //<@\compl{1}@> return min( s1.size() ? s1.top().second : oo, s2.size() ? s2.top().second : oo); diff --git a/fontes/min-stack.h b/fontes/min-stack.h index 904b5c2ac3f551dd409f8afbdd2ea052c0798c1f..f879311f8b4d3e2b2708d12acf75dfdd0d9f48c3 100644 --- a/fontes/min-stack.h +++ b/fontes/min-stack.h @@ -1,9 +1,12 @@ stack<pair<int, int>> st; -void push_el(int x) { +void push_el(int x) { //<@\compl{1}@> int m = st.empty() ? x : min(x, st.top().second); st.push({x, m}); } -int pop_el() { - int r = st.top().first; st.pop(); return r; } -int min_el() { return st.top().second; } +int pop_el() { //<@\compl{1}@> + int r = st.top().first; st.pop(); return r; +} +int min_el() { //<@\compl{1}@> + return st.top().second; +} diff --git a/fontes/next-greater-element.h b/fontes/next-greater-element.h index da7a813ebbf719be6fa2e91c60c4b0e61ead813a..4ed26c44f51af573c143181e67a99be27bd219f6 100644 --- a/fontes/next-greater-element.h +++ b/fontes/next-greater-element.h @@ -1,9 +1,11 @@ -stack<int> nge; -// start from the end for previous -for (int i = 0; i < n; i++) { - // < is greater next, > is lesser next - while (!nge.empty() && v[nge.top()] < v[i]) { - ans[nge.top()] = i; nge.pop(); +vector<int> next_greater_element(vector<int> v) { //<@\compl{n}@> + vector<int> ans (v.size()); stack<int> nge; + // start from the end for previous + for (int i = 0; i < n; i++) { + // < is greater next, > is lesser next + while (!nge.empty() && v[nge.top()] < v[i]) + ans[nge.top()] = i, nge.pop(); + nge.push(i); } - nge.push(i); + return ans; } diff --git a/fontes/number-theoretic-transform.h b/fontes/number-theoretic-transform.h index db36cc319de5b6d16651d102429c56d6c5b93024..3c813db35120a6b65e34b440ad3179b2cfad01fc 100644 --- a/fontes/number-theoretic-transform.h +++ b/fontes/number-theoretic-transform.h @@ -1,9 +1,8 @@ -void ntt (vector<mint>& a, bool rev) { +void ntt(vector<mint>& a, bool rev) { //<@\compl{n \lg n}@> int n = a.size(); auto b = a; mint g = 1; while (binary_pow(g, P/2) == 1) g += 1; if (rev) { g = binary_pow(g.x, P-2); } - for (int st = n/2; st; st /= 2) { mint w = binary_pow(g, P/(n/st)), wn = 1; for (int i = 0; i < n/2; i += st) { @@ -15,12 +14,12 @@ void ntt (vector<mint>& a, bool rev) { } swap(a, b); } - mint n1 = binary_pow(n, P-2); if (rev) for (mint& x : a) { x *= n1; } } -vector<mint> convolution (vector<mint>& a, vector<mint>& b) { +vector<mint> convolution ( + vector<mint>& a, vector<mint>& b) { vector<mint> fa (all(a)), fb (all(b)); int n = 1; while (n < a.size() + b.size()) { n *= 2; } diff --git a/fontes/pollard-rho.h b/fontes/pollard-rho.h index 1bf2067d84db7c7c321d5293938f900e989123d2..1d5ae6737bb37c4850ebdef69ac88a86c6937cfc 100644 --- a/fontes/pollard-rho.h +++ b/fontes/pollard-rho.h @@ -1,4 +1,4 @@ -ll pollard(ll n) { +ll pollard(ll n) { //<@\compl{n^{\frac{1}{4}}}@> auto f = [n](ll x) { return (fast_pow(x, x, n) + 1) % n; }; diff --git a/fontes/prim.h b/fontes/prim.h index 33dadb076a2836cf68746c914fcb835bb1a6acbe..470533ebc3b83d82704e00039dbd44161e64e27a 100644 --- a/fontes/prim.h +++ b/fontes/prim.h @@ -1,4 +1,4 @@ -ll prim(int src, int n) { +ll prim(int src, int n) { //<@\compl{(m + n)\lg n}@> vector<bool> vis (n); vector<int> par (n, -1); vector<ll> d (n, oo); vector<vector<ii>> pt (n); ll sum = 0; diff --git a/fontes/recursive-lazy-segment-tree.h b/fontes/recursive-lazy-segment-tree.h index dd638c60142a41ad77cfdb485cb46cd96c385031..0995ed6286e4c26aee044b8a9b64848696e123b0 100644 --- a/fontes/recursive-lazy-segment-tree.h +++ b/fontes/recursive-lazy-segment-tree.h @@ -1,7 +1,7 @@ vector<ll> t (4*N), lazy (4*N), sety (4*N, -1); void build(vector<int>& src, - int ti=1, int tl=1, int tr=N) { + int ti=1, int tl=1, int tr=N) { //<@\compl{n}@> if (tl == tr) { if (tl < src.size()) { t[ti] = src[tl]; } return; @@ -28,7 +28,7 @@ void push(int ti, int tl, int tm, int tr) { } void update_inclusive(int l, int r, char op, int d, - int ti=1, int tl=1, int tr=N) { + int ti=1, int tl=1, int tr=N) { //<@\compl{\lg n}@> if (l > r) { return; } if (l == tl && tr == r) { if (op == '=') { @@ -46,7 +46,7 @@ void update_inclusive(int l, int r, char op, int d, } ll op_inclusive(int l, int r, - int ti=1, int tl=1, int tr=N) { + int ti=1, int tl=1, int tr=N) { //<@\compl{\lg n}@> if (l > r) { return NEUTRAL; } if (l <= tl && tr <= r) { return t[ti]; } int tm = (tl + tr) / 2; push(ti, tl, tm, tr); diff --git a/fontes/recursive-segment-tree.h b/fontes/recursive-segment-tree.h index 10916c2e8681ff14529e904752ff0d0320cde8c3..15953450f9d4234d8fb98c6d5ceac6733591441f 100644 --- a/fontes/recursive-segment-tree.h +++ b/fontes/recursive-segment-tree.h @@ -1,7 +1,7 @@ vector<ll> t (4*N); void build(vector<ll>& src, - int ti=1, int tl=1, int tr=N) { + int ti=1, int tl=1, int tr=N) { //<@\compl{n}@> if (tl == tr) { if (tl < src.size()) { t[ti] = src[tl]; } return; @@ -13,7 +13,7 @@ void build(vector<ll>& src, } ll op_inclusive(int l, int r, - int ti=1, int tl=1, int tr=N) { + int ti=1, int tl=1, int tr=N) { //<@\compl{\lg n}@> if (l > r) { return NEUTRAL; } if (l == tl && r == tr) { return t[ti]; } int tm = (tl + tr) / 2; @@ -22,12 +22,10 @@ ll op_inclusive(int l, int r, } void set_value(int i, ll v, - int ti=1, int tl=1, int tr=N) { + int ti=1, int tl=1, int tr=N) { //<@\compl{\lg n}@> if (tl == tr) { t[ti] = v; return; } int tm = (tl + tr) / 2; - if (i <= tm) - set_value(i, v, ti*2, tl, tm); - else - set_value(i, v, ti*2+1, tm+1, tr); + if (i <= tm) { set_value(i, v, ti*2, tl, tm); } + else { set_value(i, v, ti*2+1, tm+1, tr); } t[ti] = OP(t[ti*2], t[ti*2+1]); } diff --git a/fontes/segment-tree.h b/fontes/segment-tree.h index c9869545274e9d18f5f9b7e56331cd30f07bb009..6c96c9c7433f66c83409e16524a1d0306f3a85e3 100644 --- a/fontes/segment-tree.h +++ b/fontes/segment-tree.h @@ -1,15 +1,14 @@ vector<int> t (2*N); -void build(vector<int>& src, int n) { +void build(vector<int>& src, int n) { //<@\compl{n}@> for (int i = 1; i <= n; i++) t[n+i] = src[i]; for (int ti = n-1; ti > 0; ti--) t[ti] = OP(t[2*ti], t[2*ti+1]); } -int op_inclusive(int l, int r, int n) { - r++; - int left = NEUTRAL, righ = NEUTRAL; +int op_inclusive(int l, int r, int n) { //<@\compl{\lg n}@> + r++; int left = NEUTRAL, righ = NEUTRAL; for (l += n, r += n; l < r; l /= 2, r /= 2) { if (l & 1) left = OP(left, t[l++]); if (r & 1) righ = OP(t[--r], righ); @@ -17,7 +16,7 @@ int op_inclusive(int l, int r, int n) { return OP(left, righ); } -void set_value(int i, int v, int n) { +void set_value(int i, int v, int n) { //<@\compl{\lg n}@> t[i += n] = v; for (i /= 2; i > 0; i /= 2) t[i] = OP(t[i*2], t[i*2+1]); diff --git a/fontes/sieve.h b/fontes/sieve.h index 31440de6b614641f75c1c620a8a754d65a083508..b31a6f2897b8e89298002858135b1aaa2365010d 100644 --- a/fontes/sieve.h +++ b/fontes/sieve.h @@ -1,5 +1,5 @@ vector<bool> sieve (1e7+15, 1); -void eratosthenes(int n) { +void eratosthenes(int n) { //<@\compl{n \lg \lg n}@> for (int i = 2; i * i <= n; i++) if (sieve[i]) for (int j = i * i; j <= n; j += i) sieve[j] = 0; diff --git a/fontes/small-to-large.h b/fontes/small-to-large.h index e098a046ca50bf15d7bfd7aecc212fabe4bf360a..5488fe70b5e19fecaceaf3720014ba687f8a243c 100644 --- a/fontes/small-to-large.h +++ b/fontes/small-to-large.h @@ -1,5 +1,4 @@ -vector<int> hvy (N); -vector<int> sz (N, 1); +vector<int> hvy (N), sz (N, 1); int calc_size(int u, int p) { for (int v : g[u]) if (v != p) @@ -8,12 +7,12 @@ int calc_size(int u, int p) { } void dfs_add(int u, int p, int x) { - // add + // implement add for (int v : g[u]) if (v != p && !hvy[v]) dfs_add(v, u, x); } -void small_large(int u, int p, bool keep) { +void small_large(int u, int p, bool keep) { //<@\compl{n\lg n}@> int mx = -1, h = -1; for (int v : g[u]) if (v != p && sz[v] > mx) { mx = sz[v]; h = v; @@ -22,7 +21,7 @@ void small_large(int u, int p, bool keep) { small_large(v, u, 0); if (h != -1) { small_large(h, u, 1); hvy[h] = 1; } dfs_add(u, p, +1); - // solve queries + // solve queries for u if (h != -1) { hvy[h] = 0; } if (keep == 0) { dfs_add(u, p, -1); } } diff --git a/fontes/sparse-table.h b/fontes/sparse-table.h index c54a2a8504ec6870677756be8f3769b38a14a97f..c42a221988914fcbafb537bc05a09c0a4446a136 100644 --- a/fontes/sparse-table.h +++ b/fontes/sparse-table.h @@ -1,19 +1,15 @@ const int K = 25; -vector<int> lg (N+1); vector<vector<int>> st (N, vector<int>(K+1)); -void build(vector<int>& src) { - lg[1] = 0; - for (int i = 2; i <= N; i++) { lg[i] = lg[i/2] + 1; } +void build(vector<int>& src) { //<@\compl{n \lg n}@> for (int i = 0; i < src.size(); i++) st[i][0] = src[i]; - for (int j = 1; j <= K; j++) for (int i = 0; i + (1 << j) <= N; i++) st[i][j] = min(st[i][j-1], st[i+(1 << (j-1))][j-1]); } -int min_inclusive(int l, int r) { - int j = lg[r-l+1]; +int min_inclusive(int l, int r) { //<@\compl{1}@> + int j = __lg(r-l+1); return min(st[l][j], st[r-(1 << j)+1][j]); } diff --git a/fontes/spfa.h b/fontes/spfa.h index 661c124255953598361e3501dc067da7963cb2b8..58cd40d8f986ce9fe531c8884cd7cee2fd0e3a0b 100644 --- a/fontes/spfa.h +++ b/fontes/spfa.h @@ -1,4 +1,4 @@ -bool spfa(int src, int n) { +bool spfa(int src, int n) { //<@\compl{nm}@> vector<int> cnt (n); vector<bool> queu (n); vector<ll> d (n, oo); queue<int> q; q.push(src); d[src] = 0; diff --git a/fontes/stable-matching.h b/fontes/stable-matching.h index ff39bf1a9f7a0d42eb2dc44dde7eb025052ac2c2..18a49d54e71d62de9f4d010d8ef9bd146ae8338c 100644 --- a/fontes/stable-matching.h +++ b/fontes/stable-matching.h @@ -3,12 +3,10 @@ vector<vi> pwix (N, vi(N+1)); // [w][m] = j vector<bool> single (N, 1); vector<int> match (N, -1), watch (N, N); -vector<ii> galeshapley(int n) { - // sentinel +vector<ii> galeshapley(int n) { //<@\compl{n^2}@> for (int w = 0; w < n; w++) { pwix[w][n] = n; } bool done = 0; - while (!done) { - done = 1; + while (!done) { done = 1; for (int m = 0; m < n; m++) if (single[m]) { done = 0; match[m] += 1; int w = pm[m][match[m]]; diff --git a/fontes/stoer-wagner.h b/fontes/stoer-wagner.h index 65a50eecc31e79813896ba4d3788a58900e6b501..5a6f76f2a528f38783c894fd3a2530f2b61114a7 100644 --- a/fontes/stoer-wagner.h +++ b/fontes/stoer-wagner.h @@ -22,7 +22,7 @@ int contract(int n, int &s, int &t) { return mincut; } -int stoer_wagner(int n) { +int stoer_wagner(int n) { //<@\compl{nm + n^2\lg n}@> int mincut = oo, s, t; for (int i = 0; i < n-1; i++) { mincut = min(mincut, contract(n, s, t)); diff --git a/fontes/suffix-array-radix.h b/fontes/suffix-array-radix.h index 0837d4f35d9e1af2e60066e759f9fd6640d3c652..7c2739f5644cc3ad9748abb84c012bae4ac47e26 100644 --- a/fontes/suffix-array-radix.h +++ b/fontes/suffix-array-radix.h @@ -3,7 +3,7 @@ pair<vector<int>, vector<int>> build_sa(string s, int n) { vector<pair<int, int>> a (n); for (int i = 0; i < n; i++) { a[i] = { s[i], i }; } sort(all(a)); - for (int i = 0; i < n; i++) { tie(sk[i], sa[i]) = a[i]; } + for (int i = 0; i < n; i++) { tie(sk[i],sa[i]) = a[i]; } vector<int> nsk(n); for (int i = 1, r = 0; i < n; i++) nsk[sa[i]] = (sk[i-1] == sk[i] ? r : ++r); diff --git a/fontes/tarjan.h b/fontes/tarjan.h index 1b549b84a9bf6ea092c87c93fb08e24c9fe773df..321b7772f5acb3ae6aacf8efa7016bf83d8b6aae 100644 --- a/fontes/tarjan.h +++ b/fontes/tarjan.h @@ -1,6 +1,5 @@ vector<int> tin (N, -1), lowlnk (N, -1), rep (N); -stack<int> st, topo; -int cts = 1; +stack<int> st, topo; int cts = 1; void dfs_tarjan(int u) { if (tin[u] != -1) { return; } @@ -19,7 +18,7 @@ void dfs_tarjan(int u) { } } -stack<int> tarjan(int n) { +stack<int> tarjan(int n) { //<@\compl{n+m}@> for (int u = 0; u < n; u++) { dfs_tarjan(u); } return topo; } diff --git a/fontes/topological-order.h b/fontes/topological-order.h index dbf4edb3b648d8c9a6ef00fab13ec5316738c283..613421f43182686483133043daed20f09a273e68 100644 --- a/fontes/topological-order.h +++ b/fontes/topological-order.h @@ -7,7 +7,7 @@ void dfs_topo(int u) { st.push(u); } -vector<int> toposort(int n) { +vector<int> toposort(int n) { //<@\compl{n+m}@> fill(begin(vis), begin(vis)+n, 0); vector<int> topo; for (int u = 0; u < n; u++) { dfs_topo(u); } diff --git a/fontes/tree-square-root-decomposition.h b/fontes/tree-square-root-decomposition.h index 5a9f3b9a7abcfe134cdbf858e0c3f6d7d8ba638b..416a7eb01c1613d7cc33ad448fc1618e066d2d90 100644 --- a/fontes/tree-square-root-decomposition.h +++ b/fontes/tree-square-root-decomposition.h @@ -1,7 +1,7 @@ vector<int> up (N), bup (N), depth (N); vector<ll> weiop (N), bweiop (N); -void stdt_decompose(int u, int p, int w) { +void stdt_decompose(int u, int p, int w) { //<@\compl{n+m}@> up[u] = p; weiop[u] = w; depth[u] = depth[p] + 1; bup[u] = depth[u] % B ? bup[p] : p; @@ -10,7 +10,7 @@ void stdt_decompose(int u, int p, int w) { stdt_decompose(v, u, w); } -int stdt_op(int a, int b) { +int stdt_op(int a, int b) { //<@\compl{\sqrt{n}}@> int ans = NEUTRAL; if (!(depth[a]/B > depth[b]/B)) { swap(a, b); } while (depth[a]/B > depth[b]/B) { diff --git a/fontes/voronoi.h b/fontes/voronoi.h index 580a713211b69276214871a0a4a72f5b9d568063..cb1fbf6a200cdacc359cdce05d63f7ed0f292513 100644 --- a/fontes/voronoi.h +++ b/fontes/voronoi.h @@ -18,15 +18,15 @@ pt line_intersect(pt a, pt b, pt u, pt v) { pt circumcenter(pt a, pt b, pt c) { b = (a + b) * ld(.5); c = (a + c) * ld(.5); - return point_in_line_line( - seg(b, b + rot(vec(a, b))), seg(c, c + rot(vec(a, c)))); + return point_in_line_line(seg(b, b + rot(vec(a, b))), + seg(c, c + rot(vec(a, c)))); } ld parab_intersect(pt l, pt r, ld sw) { if (abs(l.py - r.py) < abs(l.px - r.px) * EPS) { int sign = l.px < r.px ? 1 : -1; pt m = 0.5l * (l+r); - pt v = line_intersect(m, rot(r-l), pt(0, sw), pt(1, 0)); + pt v = line_intersect(m, rot(r-l), pt(0,sw), pt(1,0)); pt w = line_intersect(m, rot(l-v), v, l-v); ld l1 = abs(v-w); ld l2 = sqrt(sq(sw-m.py) - norm(m-w)); @@ -116,13 +116,13 @@ struct beach { } }; using arc = beach::arc; -struct event { - event(ld sw, int ix) +struct ev { + ev(ld sw, int ix) : type(0), sw(sw), ix(ix) {} - event(ld sw, arc* c) : type(1), sw(sw), + ev(ld sw, arc* c) : type(1), sw(sw), prv(c->prv->ix), cur(c), nxt(c->nxt->ix) {} int type, ix, prv, nxt; arc* cur; ld sw; - bool operator>(const event &l) const { return sw > l.sw; } + bool operator>(const ev& l) const { return sw > l.sw; } }; struct voronoi_t { @@ -132,7 +132,7 @@ struct voronoi_t { voronoi_t fortune(vector<pt> &ps) { voronoi_t ans; beach line; - priority_queue<event, vector<event>, greater<event>> e; + priority_queue<ev, vector<ev>, greater<ev>> e; auto add_edge = [&](int u, int v, int a, int b, arc* c1, arc* c2) { @@ -145,8 +145,8 @@ voronoi_t fortune(vector<pt> &ps) { if (ix % 2 == 0) { ans.dy[ix/2].first = v; } else { ans.dy[ix/2].second = v; } }; - auto add_event = [&](arc* cur) { - ld nxt; if (line.get(cur, nxt)) { e.emplace(nxt, cur); } + auto add_event = [&](arc* cur) { ld nxt; + if (line.get(cur, nxt)) { e.push({nxt, cur}); } }; int n = ps.size(), cnt = 0; @@ -176,7 +176,7 @@ voronoi_t fortune(vector<pt> &ps) { } else { e.emplace(psi[i].first.py, i); } } while (e.size()) { - event q = e.top(); e.pop(); + ev q = e.top(); e.pop(); arc *prv, *cur, *nxt, *si; int v = ans.v.size(), ix = q.ix; line.sw = q.sw; diff --git a/generate.sh b/generate.sh index 6f9a08a10f435c547f24fec75bdc9f690f2247f0..c07ed3342d60a736927de41bc11e91a7bfc574a9 100644 --- a/generate.sh +++ b/generate.sh @@ -1,11 +1,9 @@ mkdir -p fontes-com-hash for arq in fontes/*; do - arq=$(basename $arq) - cat </dev/null >fontes-com-hash/$arq - n=1 - while IFS="" read -r line || [ -n "$line" ]; do - hashed=$(bash fontes/hash.sh fontes/$arq 1 $n) - echo "$hashed <@\$`printf %02d $n`\$@> $line" >>fontes-com-hash/$arq - n=$((n+1)) - done <fontes/$arq + echo $(basename $arq) + if [ ! -z "$(tail -c 1 <"$arq")" ]; then + echo "WARNING: $arq does not end with a newline" + fi + grep --color '.\{59\}' $arq + bash fontes/hash.sh <$arq >fontes-com-hash/$(basename $arq) done