diff --git a/caderno.pdf b/caderno.pdf
index 7714cc621aef8714e5683bd461e4a4018e148806..04e48e5e28662cb1bee84cd621640096a5c8cdbd 100644
Binary files a/caderno.pdf and b/caderno.pdf differ
diff --git a/caderno/caderno.tex b/caderno/caderno.tex
index 029cdd13df74d4e65a814e608e5cc6135de7c3b4..bf2079f951cb228284661f231fda39e8412c91a4 100644
--- a/caderno/caderno.tex
+++ b/caderno/caderno.tex
@@ -229,7 +229,7 @@ uma das partes do corte mínimo.
 \subsection{Fatorial e desarranjos}
 \begin{align*}
   n! &\approxeq \sqrt{2\pi n} \left(\frac{n}{e}\right)^n \\
-  !n &= n!\sum_{i=0}^{n} \frac{(-1)^i)}{i!} \text{ para } n \ge 0 \\
+  !n &= n!\sum_{i=0}^{n} \frac{(-1)^i}{i!} \text{ para } n \ge 0 \\
   !n &= \left\lfloor \frac{n! + 1}{e} \right\rfloor \text{ para } n \ge 1 \\
   !n &= n(!(n-1)) + (-1)^n \text{ para } n > 0
 \end{align*}
@@ -270,7 +270,7 @@ Então:
 \begin{itemize}
   \item $\mathcal{L}(\mathbb{Z}^2)$ escala $\mathbb{Z}^2$ em $\sqrt{2}$ e rotaciona em $\frac{\pi}{4}$ em sentido horário.
   \item Para algum $p \in \mathbb{Z}^2$, $\mathcal{L}(\{ q : M(q, p) \le d \})$ (círculo) forma um quadrado alinhado
-    nos eixos em $\mathcal{L}(\mathbb{Z})^2$, com canto inferior-esquerda em $\mathcal{L}(p) - (d, d)$ e canto superior-direito em $\mathcal{L}(p) + (d, d)$.
+    nos eixos em $\mathcal{L}(\mathbb{Z})^2$, com canto inferior-esquerdo em $\mathcal{L}(p) - (d, d)$ e canto superior-direito em $\mathcal{L}(p) + (d, d)$.
   \item $M(p, q) = C(\mathcal{L}(p), \mathcal{L}(q))$, e $C(p, q) = M(\mathcal{L}^{-1}(p), \mathcal{L}^{-1}(q))$.
 \end{itemize}
 
diff --git a/fontes/circle-line-intersection.h b/fontes/circle-line-intersection.h
new file mode 100644
index 0000000000000000000000000000000000000000..ea107f85a84155cdee7bc8527b432c6c65f2d257
--- /dev/null
+++ b/fontes/circle-line-intersection.h
@@ -0,0 +1,22 @@
+using line = tuple<ll, ll, ll>;
+
+vector<pt> circle_line_intersection(double r, line abc) {
+  auto [a, b, c] = abc; vector<pt> ans;
+  double a2b2 = (a*a+b*b), x0 = -a*c/a2b2, y0 = -b*c/a2b2;
+  if (c*c > r*r*a2b2+EPS) {
+    /* zero points */
+  }
+  else if (abs(c*c - r*r*a2b2) < EPS)
+    ans.emplace_back(x0, y0);
+  else {
+    double d = r*r - c*c/a2b2, m = sqrt(d/a2b2);
+    ans.emplace_back(x0 + b*m, y0 - a*m);
+    ans.emplace_back(x0 - b*m, y0 + a*m);
+  }
+  return ans;
+}
+
+line get_line(pt p, pt q) {
+  double a = q.py - p.py, b = p.px - q.px;
+  return make_tuple(a, b, a*p.px + b*p.py);
+}
diff --git a/fontes/dinic.h b/fontes/dinic.h
index 5b01160537bcf01dd9c7febd69e0a1c9d74d0a94..85c99c6eea3fb0aadfb251d007ef34393064ad95 100644
--- a/fontes/dinic.h
+++ b/fontes/dinic.h
@@ -1,13 +1,13 @@
 vector<vector<int>> res (N);
 vector<int> level (N), ptr (N);
-struct edge { int u, v; ll cap, flow = 0; };
+struct edge { int u, v; ll cap; };
 vector<edge> edges; queue<int> q;
 
 bool minimum_path(int s, int t) {
   while (!q.empty()) {
     int u = q.front(); q.pop();
     for (int i : res[u]) {
-      if (edges[i].cap - edges[i].flow < 1) { continue; }
+      if (edges[i].cap < 1) { continue; }
       if (level[edges[i].v] != -1) { continue; }
       level[edges[i].v] = level[u] + 1;
       q.push(edges[i].v);
@@ -22,11 +22,10 @@ ll dfs(int u, int t, ll pushed) {
   for (int& cid = ptr[u]; cid < res[u].size(); cid++) {
     int i = res[u][cid], v = edges[i].v;
     if (level[u] + 1 != level[v]) { continue; }
-    if (edges[i].cap - edges[i].flow < 1) { continue; }
-    ll tr = dfs(v, t,
-        min(pushed, edges[i].cap - edges[i].flow));
+    if (edges[i].cap < 1) { continue; }
+    ll tr = dfs(v, t, min(pushed, edges[i].cap));
     if (tr == 0) { continue; }
-    edges[i].flow += tr; edges[i^1].flow -= tr;
+    edges[i].cap -= tr; edges[i^1].cap += tr;
     return tr;
   }
   return 0;
diff --git a/fontes/interval-set.h b/fontes/interval-set.h
index 8db08b75ade7a399065bbbb4b1c2e833a7b42b88..b6824a38822c01b71e3a995fc132dc7cbfc11d38 100644
--- a/fontes/interval-set.h
+++ b/fontes/interval-set.h
@@ -1,34 +1,34 @@
 struct itvl {
+  itvl(int _a = 0) : a(_a) {}
+  itvl(int _a, int _b, int _c) : a(_a), b(_b), c(_c) { }
   int a, b, c;
-  itvl(int _a, int _b, int _c)
-    : a(_a), b(_b), c(_c) {}
-  bool operator<(const itvl& o) const {
-    return ii(b, a) < ii(o.b, o.a); }
-  bool operator<(const int& o) const { return b < o; }
+  bool operator<(const itvl &b) const { return a < b.a; }
 };
 
-set<itvl, less<>> si;
+set<itvl> si;
 
-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)
-      && prev(it)->b+1 == a && prev(it)->c == c) {
-    auto prv = prev(it); int prva = prv->a;
-    si.erase(prv); a = prva;
-  }
-  if (it != end(si) && c == it->c && b+1 == it->a) {
-    int nxtb = it->b; si.erase(it); b = nxtb;
-  }
-  si.insert(itvl(a, b, c));
+void erase_sub(int m) {
+  auto it = si.lower_bound(m);
+  if (it == begin(si)) { return; } it--;
+  if (it->b <= m) { return; }
+  auto cur = *it; si.erase(it);
+  si.insert(itvl(cur.a, m, cur.c));
+  si.insert(itvl(m, cur.b, cur.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);
-    if (ori.a < a) { ins_in(itvl(ori.a, a-1, v)); }
-    if (ori.b > b) { ins_in(itvl(b+1, ori.b, v)); }
-  }
-  ins_in(itvl(a, b, c));
+void erase(int a, int b) {
+  if (a >= b) return;
+  erase_sub(a); erase_sub(b);
+  si.erase(si.lower_bound(a), si.lower_bound(b));
+}
+
+void upd_color_inclusive(int a, int b, int c) {
+  erase(a, b+1); si.insert(itvl(a, b+1, c));
+}
+
+const itvl* get(int i) {
+  auto it = si.upper_bound(i);
+  if (it == begin(si)) { return NULL; } it--;
+  if (!(it->a <= i && i < it->b)) { return NULL; }
+  return &*it;
 }
diff --git a/fontes/kadane.h b/fontes/kadane.h
index eb07582aa05a84f2ff0c04c8e100048a1ad34608..5fe0af5e8630ce4a1254c0b297beacd13f0eda35 100644
--- a/fontes/kadane.h
+++ b/fontes/kadane.h
@@ -10,4 +10,4 @@ struct kadane {
     a.ans = max({ l.ans, r.ans, l.suf + r.pre });
     return a;
   }
-}
+};
diff --git a/fontes/kruskal.h b/fontes/kruskal.h
index c0f2bddfaae02977e5b28ef341ea7f8eb41e5965..471b54adc17a1396f974c0a155c60f1340e40ffa 100644
--- a/fontes/kruskal.h
+++ b/fontes/kruskal.h
@@ -9,7 +9,7 @@ int kruskal(int n) { //<@\compl{m\alpha(n)}@>
   for (auto [u, v, w] : edges) {
     if (components == 1) { break; }
     if (ds_find(u) != ds_find(v)) {
-      ds_union(u, v);
+      ds_unite(u, v);
       components--;
       sum += w;
     }
diff --git a/fontes/lazy-segment-tree.h b/fontes/lazy-segment-tree.h
index 64115a750843cfb923a6f37e4093c8d7a66c0ca0..503fd2b46cbb07f061d68f1803cbe4643f802f91 100644
--- a/fontes/lazy-segment-tree.h
+++ b/fontes/lazy-segment-tree.h
@@ -7,6 +7,7 @@ void build(vector<int>& src, int n) { //<@\compl{n}@>
     t[n+i] = src[i];
   for (int ti = n-1; ti > 0; ti--)
     t[ti] = OP(t[2*ti], t[2*ti+1]);
+  fill(begin(delta), begin(delta)+2*n, dlta());
 }
 
 ll apply(int ti, dlta d, int sz) {
diff --git a/fontes/mo-algorithm.h b/fontes/mo-algorithm.h
index 89e3ea60e69f6e189f349cf410ae9beb4fb5c70a..6fc4c21af5418480bddae544c144bf9d88faa9f2 100644
--- a/fontes/mo-algorithm.h
+++ b/fontes/mo-algorithm.h
@@ -1,4 +1,4 @@
-vector<int> mo(vector<qry> qs) {
+vector<int> mo(vector<qry> qs) { //<@\compl{(N+Q)F\sqrt{N}}@>
   vector<int> ans (qs.size());
   sort(all(qs), [](qry a, qry b) {
     if (a.l/B != b.l/B) { return a.l < b.l; }
diff --git a/fontes/sos.h b/fontes/sos.h
index 01b394645ec51731532aca2c6214caf5b0b24de7..d672db51d29df399bd31705f8a57670f8c6d3a79 100644
--- a/fontes/sos.h
+++ b/fontes/sos.h
@@ -3,6 +3,6 @@ vector<ll> sos_dp(vector<ll> f) {
   assert((1<<n) == f.size());
   for (int i = 0; i < n; i++)
   for (int mask = 0; mask < (1<<n); mask++)
-    if (mask>>i&1) f[mask] += f[mask^(1<<i)];
+    if (mask&(i<<1)) f[mask] += f[mask^(1<<i)];
   return f;
 }