diff --git a/README.md b/README.md index 06182a23c2c12efef9498f23b21598abc711a9de..34ee963f1d6e2839721359bbf88b587adb0e273c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,11 @@ -# Implementações de algoritmos e resoluções de problemas +# Implementações de algoritmos -Estudo, treino e consulta para programação competitiva (maratona de programação) -Os algoritmos estão classificados por categorias e todos eles estão listados nas Issues. +Estudo, treino e consulta para programação competitiva (maratona de programação). + +## Requisitos (gen_notebook) +``` +$ sudo apt install texlive-latex-base +$ sudo apt install texlive-latex-recommended +$ sudo apt install texlive-formats-extra +$ sudo apt install texlive-luatex +``` diff --git a/algorithms/geometry/circle.cpp b/algorithms/geometry/circle.cpp index 179a8ba266b20d570ef8bfbd6e8b8248cb4e2796..32f9660f715c6dfb575470196df8525ff2478cf4 100644 --- a/algorithms/geometry/circle.cpp +++ b/algorithms/geometry/circle.cpp @@ -1,48 +1,48 @@ /// Circle struct Circle { - Point<> c; - double r; + Point<> c; + double r; - Circle(Point<> c, double r) : c(c), r(r) {} + Circle(Point<> c, double r) : c(c), r(r) {} - // Circumcircle - Circle(Point<> a, Point<> b, Point<> c) { - Point<> u((b - a).y, -(b - a).x); - Point<> v((c - a).y, -(c - a).x); - Point<> n = (c - b)*0.5; + // Circumcircle + Circle(Point<> a, Point<> b, Point<> c) { + Point<> u((b - a).y, -(b - a).x); + Point<> v((c - a).y, -(c - a).x); + Point<> n = (c - b)*0.5; - double t = u.cross(n) / v.cross(u); + double t = u.cross(n) / v.cross(u); - this->c = (a + c)*0.5 + v*t; - this->r = dist(this->c, a); - } + this->c = (a + c)*0.5 + v*t; + this->r = dist(this->c, a); + } - // Minimum enclosing circle: O(n) - Circle(vector<Point<>> p) { - random_shuffle(all(p)); - Circle C(p[0], 0.0); + // Minimum enclosing circle: O(n) + Circle(vector<Point<>> p) { + random_shuffle(all(p)); + Circle C(p[0], 0.0); - for (int i = 0; i < p.size(); ++i) { - if (C.contains(p[i])) continue; - C = Circle(p[i], 0.0); + for (int i = 0; i < p.size(); ++i) { + if (C.contains(p[i])) continue; + C = Circle(p[i], 0.0); - for (int j = 0; j < i; ++j) { - if (C.contains(p[j])) continue; - C = Circle((p[j] + p[i])*0.5, 0.5*dist(p[j], p[i])); + for (int j = 0; j < i; ++j) { + if (C.contains(p[j])) continue; + C = Circle((p[j] + p[i])*0.5, 0.5*dist(p[j], p[i])); - for (int k = 0; k < j; ++k) { - if (C.contains(p[k])) continue; - C = Circle(p[j], p[i], p[k]); + for (int k = 0; k < j; ++k) { + if (C.contains(p[k])) continue; + C = Circle(p[j], p[i], p[k]); + } + } } - } - } - this->c = C.c; - this->r = C.r; - } + this->c = C.c; + this->r = C.r; + } - bool contains(Point<double> p) { - return (dist(c, p) <= r + EPS); - } + bool contains(Point<> p) { + return (dist(c, p) <= r + EPS); + } }; diff --git a/algorithms/geometry/convex_hull.cpp b/algorithms/geometry/convex_hull.cpp index 279e717ca315fff7ff5cfcea467e4f8fb1c2d8dd..7004ce82d5607f460ba7fd235ca54cc774e33747 100644 --- a/algorithms/geometry/convex_hull.cpp +++ b/algorithms/geometry/convex_hull.cpp @@ -3,28 +3,30 @@ /// Time: O(n log n) /// Space: O(n) -bool cw(Point<> a, Point<> b, Point<> c) { - return (b - a).cross(c - a) <= 0; +template <typename T> +bool cw(Point<T> a, Point<T> b, Point<T> c) { + return (b - a).cross(c - a) <= 0; } -vector<Point<>> convex_hull(vector<Point<>> &v) { - int k = 0; - vector<Point<>> ans(v.size() * 2); +template <typename T> +vector<Point<T>> convex_hull(vector<Point<T>> &v) { + int k = 0; + vector<Point<T>> ans(v.size() * 2); - sort(all(v), [](const Point<> &a, const Point<> &b) { - return (a.x == b.x) ? (a.y < b.y) : (a.x < b.x); - }); + sort(all(v), [](const Point<T> &a, const Point<T> &b) { + return (a.x == b.x) ? (a.y < b.y) : (a.x < b.x); + }); - for (int i = 0; i < v.size(); ++i) { - for (; k >= 2 && cw(ans[k-2], ans[k-1], v[i]); --k); - ans[k++] = v[i]; - } + for (int i = 0; i < v.size(); ++i) { + for (; k >= 2 && cw(ans[k-2], ans[k-1], v[i]); --k); + ans[k++] = v[i]; + } - for (int i = v.size() - 2, t = k + 1; i >= 0; --i) { - for (; k >= t && cw(ans[k-2], ans[k-1], v[i]); --k); - ans[k++] = v[i]; - } + for (int i = v.size() - 2, t = k + 1; i >= 0; --i) { + for (; k >= t && cw(ans[k-2], ans[k-1], v[i]); --k); + ans[k++] = v[i]; + } - ans.resize(k); - return ans; + ans.resize(k); + return ans; } diff --git a/algorithms/geometry/point.cpp b/algorithms/geometry/point.cpp index a3f66abd6aeb62bf9e954a179764fc1f4378af18..24db5b91474a646533b232c11a5e83aabbdfeed4 100644 --- a/algorithms/geometry/point.cpp +++ b/algorithms/geometry/point.cpp @@ -2,49 +2,49 @@ template <typename T = double> struct Point { - T x, y; - - Point() {} - Point(T x, T y) : x(x), y(y) {} - - Point operator+(Point p) { return Point(x+p.x, y+p.y); } - Point operator-(Point p) { return Point(x-p.x, y-p.y); } - Point operator*(T s) { return Point(x*s, y*s); } - - T dot(Point p) { return (x*p.x) + (y*p.y); } - T cross(Point p) { return (x*p.y) - (y*p.x); } - - // Returns angle between this and p: - // atan2(y, x) is in the range [-180,180]. To - // get [0, 360], atan2(-y, -x) + 180 is used - T angle(Point p) { - return to_deg(atan2(-cross(p), -dot(p))) + 180.0; - } - - // Returns cosine value between this and p. - T cosine(Point p) { - return (dot(p) / (sqrt(dot(*this))*sqrt(p.dot(p)))); - } - - // Returns sine value between this and p. - T sine(Point p) { - return (cross(p) / (sqrt(dot(*this))*sqrt(p.dot(p)))); - } - - // Returns whether point is inside the triable - // abc or not. - bool inside_triagle(Point a, Point b, Point c) { - bool c1 = (*this - b).cross(a - b) < 0; - bool c2 = (*this - c).cross(b - c) < 0; - bool c3 = (*this - a).cross(c - a) < 0; - return c1 == c2 && c1 == c3; - } - - // Finds orientation of ordered triplet (a,b,c). - // Colinear (0), Clockwise (1), Counterclockwise (2) - static int orientation(Point<> a, Point<> b, Point<> c) { - T val = (b - a).cross(c - b); - if (val == 0) return 0; - return (val > 0) ? 1 : 2; - } + T x, y; + + Point() {} + Point(T x, T y) : x(x), y(y) {} + + Point operator+(Point p) { return Point(x+p.x, y+p.y); } + Point operator-(Point p) { return Point(x-p.x, y-p.y); } + Point operator*(T s) { return Point(x*s, y*s); } + + T dot(Point p) { return (x*p.x) + (y*p.y); } + T cross(Point p) { return (x*p.y) - (y*p.x); } + + // Returns angle between this and p: + // atan2(y, x) is in the range [-180,180]. To + // get [0, 360], atan2(-y, -x) + 180 is used + T angle(Point p) { + return to_deg(atan2(-cross(p), -dot(p))) + 180.0; + } + + // Returns cosine value between this and p. + T cosine(Point p) { + return (dot(p) / (sqrt(dot(*this))*sqrt(p.dot(p)))); + } + + // Returns sine value between this and p. + T sine(Point p) { + return (cross(p) / (sqrt(dot(*this))*sqrt(p.dot(p)))); + } + + // Returns whether point is inside the triable + // abc or not. + bool inside_triagle(Point a, Point b, Point c) { + bool c1 = (*this - b).cross(a - b) < 0; + bool c2 = (*this - c).cross(b - c) < 0; + bool c3 = (*this - a).cross(c - a) < 0; + return c1 == c2 && c1 == c3; + } + + // Finds orientation of ordered triplet (a,b,c). + // Colinear (0), Clockwise (1), Counterclockwise (2) + static int orientation(Point a, Point b, Point c) { + T val = (b - a).cross(c - b); + if (val == 0) return 0; + return (val > 0) ? 1 : 2; + } }; diff --git a/algorithms/geometry/polygon.cpp b/algorithms/geometry/polygon.cpp index 97db8be7a036a9b39b6aa3fe5509f8550d411b69..2fb010a208d7bf1dcccf247e3af676a3c82bdd99 100644 --- a/algorithms/geometry/polygon.cpp +++ b/algorithms/geometry/polygon.cpp @@ -2,64 +2,64 @@ template <typename T = double> struct Polygon { - vector<Point<T>> v; + vector<Point<T>> v; - Polygon() {} - Polygon(vector<Point<T>> v) : v(v) {} + Polygon() {} + Polygon(vector<Point<T>> v) : v(v) {} - // Adds a vertex to the polygon. - void add_point(Point<T> p) { v.pb(p); } + // Adds a vertex to the polygon. + void add_point(Point<T> p) { v.pb(p); } - // Returns area of polygon (only works when vertices - // are sorted in clockwise or counterclockwise order). - double area() { - double ans = 0; - for (int i = 0; i < v.size(); ++i) - ans += v[i].cross(v[(i + 1) % v.size()]); + // Returns area of polygon (only works when vertices + // are sorted in clockwise or counterclockwise order). + double area() { + double ans = 0; + for (int i = 0; i < v.size(); ++i) + ans += v[i].cross(v[(i + 1) % v.size()]); - return fabs(ans) / 2.0; - } + return fabs(ans) / 2.0; + } + + // Rotating Calipers + double width() { + vector<Point<T>> h = convex_hull(v); - // Rotating Calipers - double width() { - vector<Point<>> h = convex_hull(v); + int n = h.size() - 1; + double ans = 1e14; - int n = h.size() - 1; - double ans = 1e14; + h[0] = h[n]; + for (int i = 1, j = 1; i <= n; ++i) { + while ((h[i] - h[i-1]).cross(h[j%n+1] - h[i-1]) > + (h[i] - h[i-1]).cross(h[j] - h[i-1])) + j = j % n + 1; - h[0] = h[n]; - for (int i = 1, j = 1; i <= n; ++i) { - while ((h[i] - h[i-1]).cross(h[j%n+1] - h[i-1]) > - (h[i] - h[i-1]).cross(h[j] - h[i-1])) - j = j % n + 1; + Segment<T> seg(h[i], h[i-1]); + ans = min(ans, seg.dist(h[j])); + } - Segment<> seg(h[i], h[i-1]); - ans = min(ans, seg.dist(h[j])); + return ans; } - return ans; - } + // Rotating Calipers + double diameter() { + vector<Point<T>> h = convex_hull(v); - // Rotating Calipers - double diameter() { - vector<Point<>> h = convex_hull(v); + if (h.size() == 1) return 0; + if (h.size() == 2) return dist(h[0], h[1]); - if (h.size() == 1) return 0; - if (h.size() == 2) return dist(h[0], h[1]); + int n = h.size() - 1; + double ans = -1e14; - int n = h.size() - 1; - double ans = -1e14; + h[0] = h[n]; + for (int i = 1, j = 1; i <= n; ++i) { + while ((h[i] - h[i-1]).cross(h[j%n+1] - h[i-1]) > + (h[i] - h[i-1]).cross(h[j] - h[i-1])) + j = j % n + 1; - h[0] = h[n]; - for (int i = 1, j = 1; i <= n; ++i) { - while ((h[i] - h[i-1]).cross(h[j%n+1] - h[i-1]) > - (h[i] - h[i-1]).cross(h[j] - h[i-1])) - j = j % n + 1; + ans = max(ans, dist(h[j], h[i])); + ans = max(ans, dist(h[j], h[i-1])); + } - ans = max(ans, dist(h[j], h[i])); - ans = max(ans, dist(h[j], h[i-1])); + return ans; } - - return ans; - } }; diff --git a/algorithms/geometry/primitives.cpp b/algorithms/geometry/primitives.cpp index 51cee514660c829ebf1c4520b17c77191f286138..e8661033fc2e5e5333ba219133280902c4697317 100644 --- a/algorithms/geometry/primitives.cpp +++ b/algorithms/geometry/primitives.cpp @@ -3,6 +3,7 @@ #define to_deg(x) ((x * 180.0) / M_PI) #define to_rad(x) ((x * M_PI) / 180.0) -double dist(Point<> a, Point<> b) { - return hypot(a.x - b.x, a.y - b.y); +template <typename T> +double dist(Point<T> a, Point<T> b) { + return hypot(a.x - b.x, a.y - b.y); } diff --git a/algorithms/geometry/segment.cpp b/algorithms/geometry/segment.cpp index aaf4d97dce4eb077a3b81d2628619b79aebbd67f..e2afca4395172294344a5030177c79b6a0e53502 100644 --- a/algorithms/geometry/segment.cpp +++ b/algorithms/geometry/segment.cpp @@ -2,47 +2,47 @@ template <typename T = double> struct Segment { - Point<T> a, b; - - Segment(Point<T> a, Point<T> b) : a(a), b(b) {} - - // Checks if points p and q are on the same side - // of the segment. - bool same_side(Point<T> p, Point<T> q) { - T cpp = (p - a).cross(b - a); - T cpq = (q - a).cross(b - a); - return ((cpp > 0 && cpq > 0) || - (cpp < 0 && cpq < 0)); - } - - // Checks if point p is on the segment. - bool on_segment(Point<T> p) { - return (p.x <= max(a.x, b.x) && - p.x >= min(a.x, b.x) && - p.y <= max(a.y, b.y) && - p.y >= min(a.y, b.y)); - } - - // Distance between segment and point - double dist(Point<T> p) { - return (a - b).cross(p - b)/sqrt((b - a).dot(b - a)); - } - - // Checks if segment intersects with s. - bool intersect(Segment<T> s) { - int o1 = Point<>::orientation( a, b, s.a); - int o2 = Point<>::orientation( a, b, s.b); - int o3 = Point<>::orientation(s.a, s.b, a); - int o4 = Point<>::orientation(s.a, s.b, b); - - if (o1 != o2 && o3 != o4) - return true; - - if (o1 == 0 && on_segment(s.a)) return true; - if (o2 == 0 && on_segment(s.b)) return true; - if (o3 == 0 && s.on_segment(a)) return true; - if (o4 == 0 && s.on_segment(b)) return true; - - return false; - } + Point<T> a, b; + + Segment(Point<T> a, Point<T> b) : a(a), b(b) {} + + // Checks if points p and q are on the same side + // of the segment. + bool same_side(Point<T> p, Point<T> q) { + T cpp = (p - a).cross(b - a); + T cpq = (q - a).cross(b - a); + return ((cpp > 0 && cpq > 0) || + (cpp < 0 && cpq < 0)); + } + + // Checks if point p is on the segment. + bool on_segment(Point<T> p) { + return (p.x <= max(a.x, b.x) && + p.x >= min(a.x, b.x) && + p.y <= max(a.y, b.y) && + p.y >= min(a.y, b.y)); + } + + // Distance between segment and point + double dist(Point<T> p) { + return (a - b).cross(p - b)/sqrt((b - a).dot(b - a)); + } + + // Checks if segment intersects with s. + bool intersect(Segment<T> s) { + int o1 = Point<T>::orientation( a, b, s.a); + int o2 = Point<T>::orientation( a, b, s.b); + int o3 = Point<T>::orientation(s.a, s.b, a); + int o4 = Point<T>::orientation(s.a, s.b, b); + + if (o1 != o2 && o3 != o4) + return true; + + if (o1 == 0 && on_segment(s.a)) return true; + if (o2 == 0 && on_segment(s.b)) return true; + if (o3 == 0 && s.on_segment(a)) return true; + if (o4 == 0 && s.on_segment(b)) return true; + + return false; + } }; diff --git a/algorithms/graph/articulations_bridges.cpp b/algorithms/graph/articulations_bridges.cpp index 7616b547b1b634a5ee67b3ef64ecdca89cd585eb..dee78c3c6e6dba3b25227462ee0f4e5427f96969 100644 --- a/algorithms/graph/articulations_bridges.cpp +++ b/algorithms/graph/articulations_bridges.cpp @@ -6,53 +6,54 @@ vector<int> graph[MAX]; struct ArticulationsBridges { - int N; - vector<int> vis, par, L, low; + int N; + vector<int> vis, par, L, low; - vector<ii> brid; - vector<int> arti; + vector<p<int>> brid; + vector<int> arti; - ArticulationsBridges(int N) : - N(N), vis(N), par(N), L(N), low(N) - { init(); } + ArticulationsBridges(int N) : + N(N), vis(N), + par(N), L(N), low(N) + { init(); } - void init() { - fill(all(L), 0); - fill(all(vis), 0); - fill(all(par), -1); - } + void init() { + fill(all(L), 0); + fill(all(vis), 0); + fill(all(par), -1); + } - void dfs(int x) { - int child = 0; - vis[x] = 1; + void dfs(int x) { + int child = 0; + vis[x] = 1; - for (auto i : graph[x]) { - if (!vis[i]) { - child++; - par[i] = x; + for (auto i : graph[x]) { + if (!vis[i]) { + child++; + par[i] = x; - low[i] = L[i] = L[x] + 1; - dfs(i); - low[x] = min(low[x], low[i]); + low[i] = L[i] = L[x] + 1; + dfs(i); + low[x] = min(low[x], low[i]); - if ((par[x] == -1 && child > 1) || - (par[x] != -1 && low[i] >= L[x])) - arti.pb(x); + if ((par[x] == -1 && child > 1) || + (par[x] != -1 && low[i] >= L[x])) + arti.pb(x); - if (low[i] > L[x]) - brid.pb(ii(x, i)); + if (low[i] > L[x]) + brid.pb(p<int>(x, i)); - } else if (par[x] != i) - low[x] = min(low[x], L[i]); + } else if (par[x] != i) + low[x] = min(low[x], L[i]); + } } - } - void run() { - for (int i = 0; i < N; ++i) - if (!vis[i]) - dfs(i); + void run() { + for (int i = 0; i < N; ++i) + if (!vis[i]) + dfs(i); - sort(all(arti)); - arti.erase(unique(all(arti)), arti.end()); - } + sort(all(arti)); + arti.erase(unique(all(arti)), arti.end()); + } }; diff --git a/algorithms/graph/bellman_ford.cpp b/algorithms/graph/bellman_ford.cpp index 3a5b959760f3e52cad75a8c6e6b62641a15078f7..291a8db66fe0fffeb88ca09912a2dcf6a16b89ea 100644 --- a/algorithms/graph/bellman_ford.cpp +++ b/algorithms/graph/bellman_ford.cpp @@ -6,39 +6,39 @@ /// Status: Tested (LA4509) struct BellmanFord { - struct Edge { int u, v, w; }; - - int N; - vector<int> dist; - vector<Edge> graph; - - BellmanFord(int N) : - N(N), dist(N) - { init(); } - - void init() { - fill(all(dist), inf); - } - - void add_edge(int u, int v, int w) { - graph.pb({ u, v, w }); - } - - int run(int s, int d) { - dist[s] = 0; - for (int i = 0; i < N; ++i) - for (auto e : graph) - if (dist[e.u] != inf && - dist[e.u] + e.w < dist[e.v]) - dist[e.v] = dist[e.u] + e.w; - - // Check for negative cycles, return -inf if - // there is one - for (auto e : graph) - if (dist[e.u] != inf && - dist[e.u] + e.w < dist[e.v]) - return -inf; - - return dist[d]; - } + struct Edge { int u, v, w; }; + + int N; + vector<int> dist; + vector<Edge> graph; + + BellmanFord(int N) : + N(N), dist(N) + { init(); } + + void init() { + fill(all(dist), inf); + } + + void add_edge(int u, int v, int w) { + graph.pb({ u, v, w }); + } + + int run(int s, int d) { + dist[s] = 0; + for (int i = 0; i < N; ++i) + for (auto e : graph) + if (dist[e.u] != inf && + dist[e.u] + e.w < dist[e.v]) + dist[e.v] = dist[e.u] + e.w; + + // Check for negative cycles, return -inf if + // there is one + for (auto e : graph) + if (dist[e.u] != inf && + dist[e.u] + e.w < dist[e.v]) + return -inf; + + return dist[d]; + } }; diff --git a/algorithms/graph/bipartite_match.cpp b/algorithms/graph/bipartite_match.cpp index b29a9c8ede5da4de175bcd1caaa65bdb8257c1df..5a55436518fb3b68d61afc547cb98711efbd6c7d 100644 --- a/algorithms/graph/bipartite_match.cpp +++ b/algorithms/graph/bipartite_match.cpp @@ -6,35 +6,35 @@ vector<int> graph[MAX]; struct BipartiteMatching { - int N; - vector<int> vis, match; - - BipartiteMatching(int N) : - N(N), vis(N), match(N) - { init(); } - - void init() { - fill(all(vis), 0); - fill(all(match), -1); - } - - int dfs(int x) { - if (vis[x]) return 0; - - vis[x] = 1; - for (auto i : graph[x]) - if (match[i] == -1 || dfs(match[i])) { - match[i] = x; - return 1; - } - - return 0; - } - - int run() { - int ans = 0; - for (int i = 0; i < N; ++i) - ans += dfs(i); - return ans; - } + int N; + vector<int> vis, match; + + BipartiteMatching(int N) : + N(N), vis(N), match(N) + { init(); } + + void init() { + fill(all(vis), 0); + fill(all(match), -1); + } + + int dfs(int x) { + if (vis[x]) return 0; + + vis[x] = 1; + for (auto i : graph[x]) + if (match[i] == -1 || dfs(match[i])) { + match[i] = x; + return 1; + } + + return 0; + } + + int run() { + int ans = 0; + for (int i = 0; i < N; ++i) + ans += dfs(i); + return ans; + } }; diff --git a/algorithms/graph/centroid_decomposition.cpp b/algorithms/graph/centroid_decomposition.cpp index 4701e866201e0dcc35139c173c06ba0a39839050..5384432e86dafdb5d5848233ca0abdb342580c35 100644 --- a/algorithms/graph/centroid_decomposition.cpp +++ b/algorithms/graph/centroid_decomposition.cpp @@ -18,43 +18,43 @@ vector<int> graph[MAX]; struct CentroidDecomposition { - vector<int> par, size, vis; - - CentroidDecomposition(int N) : - par(N), size(N), vis(N) - { init(); } - - void init() { - fill(all(vis), 0); - build(0); // 0-indexed vertices - } - - void build(int x, int p = -1) { - int n = dfs(x); - int c = get_centroid(x, n); - vis[c] = 1; - par[c] = p; - - for (auto i : graph[c]) - if (!vis[i]) - build(i, c); - } - - // Calculates size of every subtree. - int dfs(int x, int p = -1) { - size[x] = 1; - for (auto i : graph[x]) - if (i != p && !vis[i]) - size[x] += dfs(i, x); - return size[x]; - } - - int get_centroid(int x, int n, int p = -1) { - for (auto i : graph[x]) - if (i != p && size[i] > n / 2 && !vis[i]) - return get_centroid(i, n, x); - return x; - } - - int operator[](int i) { return par[i]; } + vector<int> par, size, vis; + + CentroidDecomposition(int N) : + par(N), size(N), vis(N) + { init(); } + + void init() { + fill(all(vis), 0); + build(0); // 0-indexed vertices + } + + void build(int x, int p = -1) { + int n = dfs(x); + int c = get_centroid(x, n); + vis[c] = 1; + par[c] = p; + + for (auto i : graph[c]) + if (!vis[i]) + build(i, c); + } + + // Calculates size of every subtree. + int dfs(int x, int p = -1) { + size[x] = 1; + for (auto i : graph[x]) + if (i != p && !vis[i]) + size[x] += dfs(i, x); + return size[x]; + } + + int get_centroid(int x, int n, int p = -1) { + for (auto i : graph[x]) + if (i != p && size[i] > n / 2 && !vis[i]) + return get_centroid(i, n, x); + return x; + } + + int operator[](int i) { return par[i]; } }; diff --git a/algorithms/graph/dijkstra.cpp b/algorithms/graph/dijkstra.cpp index ba7ec06081234b8d7659bedbd7f93a8d7a2a157b..be02879f59ec78b9999de579084164d537fce93a 100644 --- a/algorithms/graph/dijkstra.cpp +++ b/algorithms/graph/dijkstra.cpp @@ -12,38 +12,38 @@ vector<int> graph[MAX]; struct Dijkstra { - int N; - vector<int> dist, vis; - - Dijkstra(int N) : - N(N), dist(N), vis(N) - { init(); } - - void init() { - fill(all(vis), 0); - fill(all(dist), inf); - } - - int run(int s, int d) { - set<ii> pq; - dist[s] = 0; - pq.insert(ii(0, s)); - - while (pq.size() != 0) { - int u = pq.begin()->se; - pq.erase(pq.begin()); - - if (vis[u]) continue; - vis[u] = 1; - - for (auto i : graph[u]) { - if (!vis[i.fi] && dist[i.fi] > dist[u] + i.se) { - dist[i.fi] = dist[u] + i.se; - pq.insert(ii(dist[i.fi], i.fi)); - } - } + int N; + vector<int> dist, vis; + + Dijkstra(int N) : + N(N), dist(N), vis(N) + { init(); } + + void init() { + fill(all(vis), 0); + fill(all(dist), inf); } - return dist[d]; - } + int run(int s, int d) { + set<p<int>> pq; + dist[s] = 0; + pq.insert({0, s}); + + while (pq.size() != 0) { + int u = pq.begin()->se; + pq.erase(pq.begin()); + + if (vis[u]) continue; + vis[u] = 1; + + for (auto i : graph[u]) { + if (!vis[i.fi] && dist[i.fi] > dist[u] + i.se) { + dist[i.fi] = dist[u] + i.se; + pq.insert({dist[i.fi], i.fi}); + } + } + } + + return dist[d]; + } }; diff --git a/algorithms/graph/dinic.cpp b/algorithms/graph/dinic.cpp index f45e94ff17c22c38c6ef17b5086aee75fa2f79b3..3407114168c8b62473fb01f6cb850cae5b422773 100644 --- a/algorithms/graph/dinic.cpp +++ b/algorithms/graph/dinic.cpp @@ -6,66 +6,66 @@ /// Status: Tested (URI2882,URI2354) struct Dinic { - struct Edge { int u, f, c, r; }; + struct Edge { int u, f, c, r; }; - int N; - vector<int> depth, start; - vector<vector<Edge>> graph; + int N; + vector<int> depth, start; + vector<vector<Edge>> graph; - Dinic(int N) : - N(N), depth(N), - start(N), graph(N) - {} + Dinic(int N) : + N(N), depth(N), + start(N), graph(N) + {} - void add_edge(int u, int v, int c) { - Edge forw = { v, 0, c, (int) graph[v].size() }; - Edge back = { u, 0, 0, (int) graph[u].size() }; - graph[u].pb(forw); - graph[v].pb(back); - } + void add_edge(int u, int v, int c) { + Edge forw = { v, 0, c, (int) graph[v].size() }; + Edge back = { u, 0, 0, (int) graph[u].size() }; + graph[u].pb(forw); + graph[v].pb(back); + } - bool bfs(int s, int t) { - queue<int> Q; - Q.push(s); + bool bfs(int s, int t) { + queue<int> Q; + Q.push(s); - fill(all(depth), -1); - depth[s] = 0; + fill(all(depth), -1); + depth[s] = 0; - while (!Q.empty()) { - int v = Q.front(); Q.pop(); - for (auto i : graph[v]) - if (depth[i.u] == -1 && i.f < i.c) { - depth[i.u] = depth[v] + 1; - Q.push(i.u); + while (!Q.empty()) { + int v = Q.front(); Q.pop(); + for (auto i : graph[v]) + if (depth[i.u] == -1 && i.f < i.c) { + depth[i.u] = depth[v] + 1; + Q.push(i.u); + } } + return depth[t] != -1; } - return depth[t] != -1; - } - int dfs(int s, int t, int f) { - if (s == t) return f; + int dfs(int s, int t, int f) { + if (s == t) return f; - for ( ; start[s] < graph[s].size(); ++start[s]) { - Edge &e = graph[s][start[s]]; - if (depth[e.u] == depth[s] + 1 && e.f < e.c) { - int min_f = dfs(e.u, t, min(f, e.c - e.f)); - if (min_f > 0) { - e.f += min_f; - graph[e.u][e.r].f -= min_f; - return min_f; + for ( ; start[s] < graph[s].size(); ++start[s]) { + Edge &e = graph[s][start[s]]; + if (depth[e.u] == depth[s] + 1 && e.f < e.c) { + int min_f = dfs(e.u, t, min(f, e.c - e.f)); + if (min_f > 0) { + e.f += min_f; + graph[e.u][e.r].f -= min_f; + return min_f; + } + } } - } + return 0; } - return 0; - } - int run(int s, int t) { - int ans = 0; - while (bfs(s, t)) { - fill(all(start), 0); - while (int flow = dfs(s, t, inf)) - ans += flow; + int run(int s, int t) { + int ans = 0; + while (bfs(s, t)) { + fill(all(start), 0); + while (int flow = dfs(s, t, inf)) + ans += flow; + } + return ans; } - return ans; - } }; diff --git a/algorithms/graph/edmonds_karp.cpp b/algorithms/graph/edmonds_karp.cpp index f8e628e9597b355f1eabd63c4646f9a7ec95307f..d603f2f4cdc055986dbaac9853402867aae01f20 100644 --- a/algorithms/graph/edmonds_karp.cpp +++ b/algorithms/graph/edmonds_karp.cpp @@ -9,52 +9,52 @@ int rg[MAX][MAX]; int graph[MAX][MAX]; struct EdmondsKarp { - int N; - vector<int> par, vis; - - EdmondsKarp(int N) : - N(N), par(N), vis(N) - { init(); } - - void init() { - fill(all(vis), 0); - } - - bool bfs(int s, int t) { - queue<int> Q; - Q.push(s); - vis[s] = true; - - while (!Q.empty()) { - int u = Q.front(); Q.pop(); - if (u == t) return true; - for (int i = 0; i < N; ++i) - if (!vis[i] && rg[u][i]) { - vis[i] = true; - par[i] = u; - Q.push(i); + int N; + vector<int> par, vis; + + EdmondsKarp(int N) : + N(N), par(N), vis(N) + { init(); } + + void init() { + fill(all(vis), 0); + } + + bool bfs(int s, int t) { + queue<int> Q; + Q.push(s); + vis[s] = true; + + while (!Q.empty()) { + int u = Q.front(); Q.pop(); + if (u == t) return true; + for (int i = 0; i < N; ++i) + if (!vis[i] && rg[u][i]) { + vis[i] = true; + par[i] = u; + Q.push(i); + } } + return false; } - return false; - } - - int run(int s, int t) { - int ans = 0; - par[s] = -1; - memcpy(rg, graph, sizeof(graph)); - - while (bfs(s, t)) { - int flow = inf; - for (int i = t; par[i] != -1; i = par[i]) - flow = min(flow, rg[par[i]][i]); - - for (int i = t; par[i] != -1; i = par[i]) { - rg[par[i]][i] -= flow; - rg[i][par[i]] += flow; - } - ans += flow; - init(); + + int run(int s, int t) { + int ans = 0; + par[s] = -1; + memcpy(rg, graph, sizeof(graph)); + + while (bfs(s, t)) { + int flow = inf; + for (int i = t; par[i] != -1; i = par[i]) + flow = min(flow, rg[par[i]][i]); + + for (int i = t; par[i] != -1; i = par[i]) { + rg[par[i]][i] -= flow; + rg[i][par[i]] += flow; + } + ans += flow; + init(); + } + return ans; } - return ans; - } }; diff --git a/algorithms/graph/floyd_warshall.cpp b/algorithms/graph/floyd_warshall.cpp index d52f5bcfb5ef4f798e55065b6b77e2936fec01e4..4d97c04ac200569e135267ea1a2da28fa8c2263d 100644 --- a/algorithms/graph/floyd_warshall.cpp +++ b/algorithms/graph/floyd_warshall.cpp @@ -7,16 +7,16 @@ int dist[MAX][MAX]; int graph[MAX][MAX]; void floyd_warshall(int n) { - mset(dist, inf); + mset(dist, inf); - for (int i = 0; i < n; ++i) - for (int j = 0; j < n; ++j) - if (graph[i][j]) - dist[i][j] = graph[i][j]; - - for (int k = 0; k < n; ++k) for (int i = 0; i < n; ++i) - for (int j = 0; j < n; ++j) - dist[i][j] = min(dist[i][j], - dist[i][k] + dist[k][j]); + for (int j = 0; j < n; ++j) + if (graph[i][j]) + dist[i][j] = graph[i][j]; + + for (int k = 0; k < n; ++k) + for (int i = 0; i < n; ++i) + for (int j = 0; j < n; ++j) + dist[i][j] = min(dist[i][j], + dist[i][k] + dist[k][j]); } diff --git a/algorithms/graph/ford_fulkerson.cpp b/algorithms/graph/ford_fulkerson.cpp index fb7a77f0ef01cacbe725a728affa4b2562fdd8c6..28a3cb104f9fee4cf1067f471a979915be66b223 100644 --- a/algorithms/graph/ford_fulkerson.cpp +++ b/algorithms/graph/ford_fulkerson.cpp @@ -9,46 +9,46 @@ int rg[MAX][MAX]; int graph[MAX][MAX]; struct FordFulkerson { - int N; - vector<int> par, vis; - - FordFulkerson(int N) : - N(N), par(N), vis(N) - { init(); } - - void init() { - fill(all(vis), 0); - } - - bool dfs(int s, int t) { - vis[s] = true; - if (s == t) return true; - - for (int i = 0; i < N; ++i) - if (!vis[i] && rg[s][i]) { - par[i] = s; - if (dfs(i, t)) return true; - } - return false; - } - - int run(int s, int t) { - int ans = 0; - par[s] = -1; - memcpy(rg, graph, sizeof(graph)); - - while (dfs(s, t)) { - int flow = inf; - for (int i = t; par[i] != -1; i = par[i]) - flow = min(flow, rg[par[i]][i]); - - for (int i = t; par[i] != -1; i = par[i]) { - rg[par[i]][i] -= flow; - rg[i][par[i]] += flow; - } - ans += flow; - init(); + int N; + vector<int> par, vis; + + FordFulkerson(int N) : + N(N), par(N), vis(N) + { init(); } + + void init() { + fill(all(vis), 0); + } + + bool dfs(int s, int t) { + vis[s] = true; + if (s == t) return true; + + for (int i = 0; i < N; ++i) + if (!vis[i] && rg[s][i]) { + par[i] = s; + if (dfs(i, t)) return true; + } + return false; + } + + int run(int s, int t) { + int ans = 0; + par[s] = -1; + memcpy(rg, graph, sizeof(graph)); + + while (dfs(s, t)) { + int flow = inf; + for (int i = t; par[i] != -1; i = par[i]) + flow = min(flow, rg[par[i]][i]); + + for (int i = t; par[i] != -1; i = par[i]) { + rg[par[i]][i] -= flow; + rg[i][par[i]] += flow; + } + ans += flow; + init(); + } + return ans; } - return ans; - } }; diff --git a/algorithms/graph/hld.cpp b/algorithms/graph/hld.cpp index d8fe4269cdf1a484293fa7e7a177983e9ec2420b..7d7b658de5cdb01fe1832a33e1f831a83c9cc50e 100644 --- a/algorithms/graph/hld.cpp +++ b/algorithms/graph/hld.cpp @@ -23,92 +23,92 @@ /// /// Status: Tested (QTREE,URI2887) -ii edge[MAX]; -vector<ii> graph[MAX]; - +p<int> edge[MAX]; +vector<p<int>> graph[MAX]; + template <typename ST> struct HLD { - ST &seg; - int cnum, ptr; - - // depth, parent, value of node - vector<int> dep, par, val; - - // head[i]: head of i-th node's chain; - // heavy[i]: "special child" of i-th node - // pos[i]: position of i-th node on segtree - // bot[i]: bottommost (depth-wise) node on the i-th - // edge (required only when edges have weights) - vector<int> head, heavy, pos, bot; - - HLD(int n, ST &seg) : - seg(seg), - dep(n, 0), par(n), val(n), - head(n), heavy(n, -1), pos(n), bot(n) - { - cnum = ptr = 0; - N = n; // global N for segtree - dfs(0); - decompose(0); - - // (required only when edges have weights) - for (int i = 0; i < n - 1; ++i) - if (dep[edge[i].fi] > dep[edge[i].se]) - bot[i] = edge[i].fi; - else - bot[i] = edge[i].se; - } - - int dfs(int x, int p = -1) { - int size = 1; - par[x] = p; - - int max_size = 0; - for (auto i : graph[x]) - if (i.fi != p) { - dep[i.fi] = dep[x] + 1; - val[i.fi] = i.se; - int isize = dfs(i.fi, x); - - size += isize; - if (isize > max_size) - max_size = isize, heavy[x] = i.fi; - } - - return size; - } - - void decompose(int x, int h = 0) { - head[x] = h; - seg.update(ptr, val[x]); - pos[x] = ptr++; - - if (heavy[x] != -1) - decompose(heavy[x], h); - - for (auto i : graph[x]) - if (i.fi != par[x] && i.fi != heavy[x]) - decompose(i.fi, i.fi); - } - - // Queries max edge (or vertice) on the path - // between a and b - int query(int a, int b) { - int ans = seg.ident; - for (; head[a] != head[b]; b = par[head[b]]) { - if (dep[head[a]] > dep[head[b]]) - swap(a, b); - ans = seg.func(ans, seg.query(pos[head[b]], pos[b])); + ST &seg; + int cnum, ptr; + + // depth, parent, value of node + vector<int> dep, par, val; + + // head[i]: head of i-th node's chain; + // heavy[i]: "special child" of i-th node + // pos[i]: position of i-th node on segtree + // bot[i]: bottommost (depth-wise) node on the i-th + // edge (required only when edges have weights) + vector<int> head, heavy, pos, bot; + + HLD(int n, ST &seg) : + seg(seg), + dep(n, 0), par(n), val(n), + head(n), heavy(n, -1), pos(n), bot(n) + { + cnum = ptr = 0; + N = n; // global N for segtree + dfs(0); + decompose(0); + + // (required only when edges have weights) + for (int i = 0; i < n - 1; ++i) + if (dep[edge[i].fi] > dep[edge[i].se]) + bot[i] = edge[i].fi; + else + bot[i] = edge[i].se; + } + + int dfs(int x, int p = -1) { + int size = 1; + par[x] = p; + + int max_size = 0; + for (auto i : graph[x]) + if (i.fi != p) { + dep[i.fi] = dep[x] + 1; + val[i.fi] = i.se; + int isize = dfs(i.fi, x); + + size += isize; + if (isize > max_size) + max_size = isize, heavy[x] = i.fi; + } + + return size; + } + + void decompose(int x, int h = 0) { + head[x] = h; + seg.update(ptr, val[x]); + pos[x] = ptr++; + + if (heavy[x] != -1) + decompose(heavy[x], h); + + for (auto i : graph[x]) + if (i.fi != par[x] && i.fi != heavy[x]) + decompose(i.fi, i.fi); } - if (dep[a] > dep[b]) swap(a, b); + // Queries max edge (or vertice) on the path + // between a and b + int query(int a, int b) { + int ans = seg.ident; + for (; head[a] != head[b]; b = par[head[b]]) { + if (dep[head[a]] > dep[head[b]]) + swap(a, b); + ans = seg.func(ans, seg.query(pos[head[b]], pos[b])); + } - // Remove "+ 1" when values are associated with vertices - return seg.func(ans, seg.query(pos[a] + 1, pos[b])); - } - - // Updates value of i-th edge (or vertice) - void update(int i, int val) { - seg.update(pos[bot[i]], val); - } + if (dep[a] > dep[b]) swap(a, b); + + // Remove "+ 1" when values are associated with vertices + return seg.func(ans, seg.query(pos[a] + 1, pos[b])); + } + + // Updates value of i-th edge (or vertice) + void update(int i, int val) { + seg.update(pos[bot[i]], val); + } }; diff --git a/algorithms/graph/hopcroft_karp.cpp b/algorithms/graph/hopcroft_karp.cpp index 1897db3ab183c25add21a30561ea1b72cb04fffa..fa1063230190e7d3adc7e94b37f76689c92dcfdc 100644 --- a/algorithms/graph/hopcroft_karp.cpp +++ b/algorithms/graph/hopcroft_karp.cpp @@ -3,7 +3,7 @@ /// Time: O(E * sqrt{V}) /// Space: O(V + E) /// -/// Caution: +/// Caution: /// - Assumes 0-indexed vertices in graph; /// - The vertex enumeration on the left CAN be the same as the right. /// @@ -12,66 +12,67 @@ vector<int> graph[MAX]; struct HopcroftKarp { - int L, R; - vector<int> dist; - vector<int> matchL, matchR; + int L, R; + vector<int> dist; + vector<int> matchL, matchR; - HopcroftKarp(int L, int R) : - L(L), R(R), dist(L), - matchL(L), matchR(R) - { init(); } + HopcroftKarp(int L, int R) : + L(L), R(R), dist(L), + matchL(L), matchR(R) + { init(); } - void init() { - fill(all(matchL), -1); - fill(all(matchR), -1); - } + void init() { + fill(all(matchL), -1); + fill(all(matchR), -1); + } - bool bfs() { - queue<int> Q; - for (int l = 0; l < L; ++l) - if (matchL[l] == -1) { - dist[l] = 0; - Q.push(l); - } else - dist[l] = -1; + bool bfs() { + queue<int> Q; + for (int l = 0; l < L; ++l) + if (matchL[l] == -1) { + dist[l] = 0; + Q.push(l); + } else + dist[l] = -1; - bool ans = false; - while (!Q.empty()) { - int l = Q.front(); Q.pop(); - for (auto r : graph[l]) - if (matchR[r] == -1) - ans = true; - else if (dist[matchR[r]] == -1) { - dist[matchR[r]] = dist[l] + 1; - Q.push(matchR[r]); + bool ans = false; + while (!Q.empty()) { + int l = Q.front(); Q.pop(); + for (auto r : graph[l]) + if (matchR[r] == -1) + ans = true; + else if (dist[matchR[r]] == -1) { + dist[matchR[r]] = dist[l] + 1; + Q.push(matchR[r]); + } } - } - return ans; - } + return ans; + } - bool dfs(int l) { - if (l == -1) - return true; + bool dfs(int l) { + if (l == -1) + return true; - for (auto r : graph[l]) - if (matchR[r] == -1 || dist[matchR[r]] == dist[l] + 1) - if (dfs(matchR[r])) { - matchR[r] = l; - matchL[l] = r; - return true; - } + for (auto r : graph[l]) + if (matchR[r] == -1 || + dist[matchR[r]] == dist[l] + 1) + if (dfs(matchR[r])) { + matchR[r] = l; + matchL[l] = r; + return true; + } - return false; - } + return false; + } - int run() { - int ans = 0; - while (bfs()) - for (int l = 0; l < L; ++l) - if (matchL[l] == -1 && dfs(l)) - ans++; + int run() { + int ans = 0; + while (bfs()) + for (int l = 0; l < L; ++l) + if (matchL[l] == -1 && dfs(l)) + ans++; - return ans; - } + return ans; + } }; diff --git a/algorithms/graph/kosaraju.cpp b/algorithms/graph/kosaraju.cpp index 22a9f83b1e213fe9cb28ab4767f5a8489c563f05..46af5858af2bd9370298c4fca48fa984c406dd55 100644 --- a/algorithms/graph/kosaraju.cpp +++ b/algorithms/graph/kosaraju.cpp @@ -7,56 +7,56 @@ vector<int> graph[MAX]; vector<int> transp[MAX]; struct Kosaraju { - int N; - stack<int> S; - vector<int> vis; - - Kosaraju(int N) : - N(N), vis(N) - { init(); } - - void init() { - fill(all(vis), 0); - } - - void dfs(int x) { - vis[x] = true; - for (auto i : transp[x]) - if (!vis[i]) - dfs(i); - } - - // Fills stack with DFS starting points to find SCC. - void fill_stack(int x) { - vis[x] = true; - for (auto i : graph[x]) - if (!vis[i]) - fill_stack(i); - S.push(x); - } - - int run() { - int scc = 0; - for (int i = 0; i < N; ++i) - if (!vis[i]) - fill_stack(i); - - // Transpose graph - for (int i = 0; i < N; ++i) - for (auto j : graph[i]) - transp[j].push_back(i); - init(); - - // Count SCC - while (!S.empty()) { - int v = S.top(); - S.pop(); - if (!vis[v]) { - dfs(v); - scc++; - } + int N; + stack<int> S; + vector<int> vis; + + Kosaraju(int N) : + N(N), vis(N) + { init(); } + + void init() { + fill(all(vis), 0); + } + + void dfs(int x) { + vis[x] = true; + for (auto i : transp[x]) + if (!vis[i]) + dfs(i); } - return scc; - } + // Fills stack with DFS starting points to find SCC. + void fill_stack(int x) { + vis[x] = true; + for (auto i : graph[x]) + if (!vis[i]) + fill_stack(i); + S.push(x); + } + + int run() { + int scc = 0; + for (int i = 0; i < N; ++i) + if (!vis[i]) + fill_stack(i); + + // Transpose graph + for (int i = 0; i < N; ++i) + for (auto j : graph[i]) + transp[j].push_back(i); + init(); + + // Count SCC + while (!S.empty()) { + int v = S.top(); + S.pop(); + if (!vis[v]) { + dfs(v); + scc++; + } + } + + return scc; + } }; diff --git a/algorithms/graph/kruskal.cpp b/algorithms/graph/kruskal.cpp index 96580a56ac0cdb18a2356c90760274cec0214658..648b12329f7f33b49cb867bfcb40b6a772310c68 100644 --- a/algorithms/graph/kruskal.cpp +++ b/algorithms/graph/kruskal.cpp @@ -6,34 +6,34 @@ /// Include: /// - structure/disjoint_set -using edge = pair<ii,int>; +using edge = pair<p<int>,int>; vector<edge> edges; struct Kruskal { - int N; - DisjointSet ds; + int N; + DisjointSet ds; - Kruskal(int N) : N(N), ds(N) {} + Kruskal(int N) : N(N), ds(N) {} - // Minimum Spanning Tree: comp = less<int>() - // Maximum Spanning Tree: comp = greater<int>() - int run(vector<edge> &mst, function<bool(int,int)> comp) { - sort(all(edges), [&](const edge &a, const edge &b) { - return comp(a.se, b.se); - }); + // Minimum Spanning Tree: comp = less<int>() + // Maximum Spanning Tree: comp = greater<int>() + int run(vector<edge> &mst, function<bool(int,int)> comp) { + sort(all(edges), [&](const edge &a, const edge &b) { + return comp(a.se, b.se); + }); - int size = 0; - for (int i = 0; i < edges.size(); i++) { - int pu = ds.find_set(edges[i].fi.fi); - int pv = ds.find_set(edges[i].fi.se); + int size = 0; + for (int i = 0; i < edges.size(); i++) { + int pu = ds.find_set(edges[i].fi.fi); + int pv = ds.find_set(edges[i].fi.se); - if (pu != pv) { - mst.pb(edges[i]); - size += edges[i].se; - ds.union_set(pu, pv); - } - } + if (pu != pv) { + mst.pb(edges[i]); + size += edges[i].se; + ds.union_set(pu, pv); + } + } - return size; - } + return size; + } }; diff --git a/algorithms/graph/lca.cpp b/algorithms/graph/lca.cpp index 0a6311a55d986fb8ca368e61aa99cde395dc67c6..25d7f2d2e946e4ea94ff771381a09199d1533344 100644 --- a/algorithms/graph/lca.cpp +++ b/algorithms/graph/lca.cpp @@ -20,72 +20,72 @@ #define LOG 20 #define COST 0 -vector<ii> graph[MAX]; +vector<p<int>> graph[MAX]; int par[MAX][LOG], cost[MAX][LOG]; template <typename T, class F = function<T(T,T)>> struct LCA { - F func; - vector<int> h; + F func; + vector<int> h; - LCA(int N, F func) : h(N), func(func) - { init(); } + LCA(int N, F func) : h(N), func(func) + { init(); } - void init() { - mset(par, -1); - mset(cost, 0); - dfs(0); - } + void init() { + mset(par, -1); + mset(cost, 0); + dfs(0); + } - void dfs(int v, int p = -1, int c = 0) { - par[v][0] = p; - cost[v][0] = c; - if (p != -1) h[v] = h[p] + 1; + void dfs(int v, int p = -1, int c = 0) { + par[v][0] = p; + cost[v][0] = c; + if (p != -1) h[v] = h[p] + 1; - for (int i = 1; i < LOG; ++i) - if (par[v][i-1] != -1) { - par[v][i] = par[par[v][i-1]][i-1]; - cost[v][i] = func(cost[v][i], func(cost[v][i-1], - cost[par[v][i-1]][i-1])); - } + for (int i = 1; i < LOG; ++i) + if (par[v][i-1] != -1) { + par[v][i] = par[par[v][i-1]][i-1]; + cost[v][i] = func(cost[v][i], func(cost[v][i-1], + cost[par[v][i-1]][i-1])); + } - for (auto u : graph[v]) - if (p != u.fi) - dfs(u.fi, v, u.se); - } + for (auto u : graph[v]) + if (p != u.fi) + dfs(u.fi, v, u.se); + } - int query(int a, int b) { - int ans = 0; - if (h[a] < h[b]) swap(a, b); + int query(int a, int b) { + int ans = 0; + if (h[a] < h[b]) swap(a, b); - for (int i = LOG - 1; i >= 0; --i) - if (par[a][i] != -1 && h[par[a][i]] >= h[b]) { - ans = func(ans, cost[a][i]); - a = par[a][i]; - } + for (int i = LOG - 1; i >= 0; --i) + if (par[a][i] != -1 && h[par[a][i]] >= h[b]) { + ans = func(ans, cost[a][i]); + a = par[a][i]; + } - if (a == b) { - #ifdef COST - return ans; - #else - return a; - #endif - } + if (a == b) { +#ifdef COST + return ans; +#else + return a; +#endif + } - for (int i = LOG - 1; i >= 0; --i) - if (par[a][i] != -1 && par[a][i] != par[b][i]) { - ans = func(ans, func(cost[a][i], cost[b][i])); - a = par[a][i]; - b = par[b][i]; - } + for (int i = LOG - 1; i >= 0; --i) + if (par[a][i] != -1 && par[a][i] != par[b][i]) { + ans = func(ans, func(cost[a][i], cost[b][i])); + a = par[a][i]; + b = par[b][i]; + } - #ifdef COST - if (a == b) - return ans; - else - return func(ans, func(cost[a][0], cost[b][0])); - #else - return par[a][0]; - #endif - } +#ifdef COST + if (a == b) + return ans; + else + return func(ans, func(cost[a][0], cost[b][0])); +#else + return par[a][0]; +#endif + } }; diff --git a/algorithms/graph/min_cost_max_flow.cpp b/algorithms/graph/min_cost_max_flow.cpp index c8dd2bb0f8e3ee6aca0538feee0626a58faae444..e605db2312ebb6e31cccb45dce18cbab835d805b 100644 --- a/algorithms/graph/min_cost_max_flow.cpp +++ b/algorithms/graph/min_cost_max_flow.cpp @@ -4,73 +4,73 @@ /// Space: O(V + E) /// /// Status: Tested (UVA10594,kattis/mincostmaxflow) - + struct MinCostMaxFlow { - struct Edge { int u, v, cap, cost; }; + struct Edge { int u, v, cap, cost; }; - vector<Edge> edges; - vector<vector<int>> adj; - vector<int> vis, dist, par, ind; + vector<Edge> edges; + vector<vector<int>> adj; + vector<int> vis, dist, par, ind; - MinCostMaxFlow(int N) : - vis(N), dist(N), par(N), ind(N), adj(N) {} + MinCostMaxFlow(int N) : + vis(N), dist(N), par(N), ind(N), adj(N) {} - void add_edge(int u, int v, int cap, int cost) { - adj[u].pb(edges.size()); - edges.pb({ u, v, cap, cost }); - adj[v].pb(edges.size()); - edges.pb({ v, u, 0, -cost }); - } + void add_edge(int u, int v, int cap, int cost) { + adj[u].pb(edges.size()); + edges.pb({ u, v, cap, cost }); + adj[v].pb(edges.size()); + edges.pb({ v, u, 0, -cost }); + } - // Shortest Path Faster Algorithm (slower than - // Dijkstra but works with negative edges). - bool spfa(int s, int t) { - fill(all(dist), inf); - dist[s] = 0; - queue<int> Q; - Q.push(s); + // Shortest Path Faster Algorithm (slower than + // Dijkstra but works with negative edges). + bool spfa(int s, int t) { + fill(all(dist), inf); + dist[s] = 0; + queue<int> Q; + Q.push(s); - while (!Q.empty()) { - int u = Q.front(); Q.pop(); - vis[u] = 0; + while (!Q.empty()) { + int u = Q.front(); Q.pop(); + vis[u] = 0; - for (auto i : adj[u]) { - Edge &e = edges[i]; - int v = e.v; - if (e.cap > 0 && dist[v] > dist[u] + e.cost) { - dist[v] = dist[u] + e.cost; - par[v] = u; - ind[v] = i; + for (auto i : adj[u]) { + Edge &e = edges[i]; + int v = e.v; + if (e.cap > 0 && dist[v] > dist[u] + e.cost) { + dist[v] = dist[u] + e.cost; + par[v] = u; + ind[v] = i; - if (!vis[v]) { - Q.push(v); - vis[v] = 1; - } + if (!vis[v]) { + Q.push(v); + vis[v] = 1; + } + } + } } - } + return dist[t] < inf; } - return dist[t] < inf; - } - // Returns pair (min_cost, max_flow). - ii run(int s, int t) { - int min_cost = 0; - int max_flow = 0; + // Returns pair (min_cost, max_flow). + p<int> run(int s, int t) { + int min_cost = 0; + int max_flow = 0; - while (spfa(s, t)) { - int flow = inf; - for (int i = t; i != s; i = par[i]) - flow = min(flow, edges[ind[i]].cap); + while (spfa(s, t)) { + int flow = inf; + for (int i = t; i != s; i = par[i]) + flow = min(flow, edges[ind[i]].cap); - for (int i = t; i != s; i = par[i]) { - edges[ind[i] ].cap -= flow; - edges[ind[i]^1].cap += flow; - } + for (int i = t; i != s; i = par[i]) { + edges[ind[i] ].cap -= flow; + edges[ind[i]^1].cap += flow; + } - min_cost += flow * dist[t]; - max_flow += flow; - } + min_cost += flow * dist[t]; + max_flow += flow; + } - return ii(min_cost, max_flow); - } + return {min_cost, max_flow}; + } }; diff --git a/algorithms/graph/prim.cpp b/algorithms/graph/prim.cpp index cb3fc48d100e86149c9bbf2b466886c10c746752..94db35690b9155c1b6a4d776a81316f8b2e8df39 100644 --- a/algorithms/graph/prim.cpp +++ b/algorithms/graph/prim.cpp @@ -3,41 +3,41 @@ /// Time: O(E log E) /// Space: O(V + E) -vector<ii> graph[MAX]; +vector<p<int>> graph[MAX]; struct Prim { - int N; - vector<int> vis; - - Prim(int N) : - N(N), vis(N) - { init(); } - - void init() { - fill(all(vis), 0); - } - - int run() { - vis[0] = true; - priority_queue<ii> pq; - for (auto i : graph[0]) - pq.push(ii(-i.se, -i.fi)); - - int ans = 0; - while (!pq.empty()) { - ii front = pq.top(); pq.pop(); - int u = -front.se; - int w = -front.fi; - - if (!vis[u]) { - ans += w; - vis[u] = true; - for (auto i : graph[u]) - if (!vis[i.fi]) - pq.push(ii(-i.se, -i.fi)); - } + int N; + vector<int> vis; + + Prim(int N) : + N(N), vis(N) + { init(); } + + void init() { + fill(all(vis), 0); } - return ans; - } + int run() { + vis[0] = true; + priority_queue<p<int>> pq; + for (auto i : graph[0]) + pq.push({-i.se, -i.fi}); + + int ans = 0; + while (!pq.empty()) { + p<int> front = pq.top(); pq.pop(); + int u = -front.se; + int w = -front.fi; + + if (!vis[u]) { + ans += w; + vis[u] = true; + for (auto i : graph[u]) + if (!vis[i.fi]) + pq.push({-i.se, -i.fi}); + } + } + + return ans; + } }; diff --git a/algorithms/graph/steiner_tree.cpp b/algorithms/graph/steiner_tree.cpp index 073407be2167208c0bd99bd626d9c2b23b02b0aa..b504f9fd19c42f2d4eba712378e8253703270546 100644 --- a/algorithms/graph/steiner_tree.cpp +++ b/algorithms/graph/steiner_tree.cpp @@ -26,26 +26,26 @@ int graph[MAXN][MAXN]; int dp[MAXN][1 << MAXT]; int steiner_tree(int n, int t) { - floyd_warshall(n); + floyd_warshall(n); - mset(dp, inf); - for (int i = 0; i < t; ++i) - dp[i][1 << i] = 0; + mset(dp, inf); + for (int i = 0; i < t; ++i) + dp[i][1 << i] = 0; - for (int mask = 1; mask < (1 << t); ++mask) { - for (int i = 0; i < n; ++i) - for (int ss = mask; ss > 0; ss = (ss - 1) & mask) - dp[i][mask] = min(dp[i][mask], - dp[i][ss] + dp[i][mask ^ ss]); + for (int mask = 1; mask < (1 << t); ++mask) { + for (int i = 0; i < n; ++i) + for (int ss = mask; ss > 0; ss = (ss - 1) & mask) + dp[i][mask] = min(dp[i][mask], + dp[i][ss] + dp[i][mask ^ ss]); - for (int i = 0; i < n; ++i) - for (int j = 0; j < n; ++j) - dp[j][mask] = min(dp[j][mask], - dp[i][mask] + dist[i][j]); - } + for (int i = 0; i < n; ++i) + for (int j = 0; j < n; ++j) + dp[j][mask] = min(dp[j][mask], + dp[i][mask] + dist[i][j]); + } - int ans = inf; - for (int i = 0; i < n; ++i) - ans = min(ans, dp[i][(1 << t) - 1]); - return ans; + int ans = inf; + for (int i = 0; i < n; ++i) + ans = min(ans, dp[i][(1 << t) - 1]); + return ans; } diff --git a/algorithms/graph/tarjan.cpp b/algorithms/graph/tarjan.cpp index 09741dcfd29355fad621d840e99c2fb07be6abbf..63304961a93ba57e55e8395c4df09843061e46a1 100644 --- a/algorithms/graph/tarjan.cpp +++ b/algorithms/graph/tarjan.cpp @@ -7,54 +7,54 @@ vector<int> scc[MAX]; vector<int> graph[MAX]; struct Tarjan { - int N, ncomp, ind; - - stack<int> S; - vector<int> vis, id, low; - - Tarjan(int N) : - N(N), vis(N), id(N), low(N) - { init(); } - - void init() { - fill(all(id), -1); - fill(all(vis), 0); - } - - void dfs(int x) { - id[x] = low[x] = ind++; - vis[x] = 1; - S.push(x); - - for (auto i : graph[x]) - if (id[i] == -1) { - dfs(i); - low[x] = min(low[x], low[i]); - } else if (vis[i]) - low[x] = min(low[x], id[i]); - - // A SCC was found - if (low[x] == id[x]) { - int w; - do { - w = S.top(); S.pop(); - vis[w] = 0; - scc[ncomp].pb(w); - } while (w != x); - ncomp++; + int N, ncomp, ind; + + stack<int> S; + vector<int> vis, id, low; + + Tarjan(int N) : + N(N), vis(N), id(N), low(N) + { init(); } + + void init() { + fill(all(id), -1); + fill(all(vis), 0); + } + + void dfs(int x) { + id[x] = low[x] = ind++; + vis[x] = 1; + S.push(x); + + for (auto i : graph[x]) + if (id[i] == -1) { + dfs(i); + low[x] = min(low[x], low[i]); + } else if (vis[i]) + low[x] = min(low[x], id[i]); + + // A SCC was found + if (low[x] == id[x]) { + int w; + do { + w = S.top(); S.pop(); + vis[w] = 0; + scc[ncomp].pb(w); + } while (w != x); + ncomp++; + } + } + + int run() { + init(); + ncomp = ind = 0; + for (int i = 0; i < N; ++i) + scc[i].clear(); + + // Apply tarjan in every component + for (int i = 0; i < N; ++i) + if (id[i] == -1) + dfs(i); + return ncomp; } - } - - int run() { - init(); - ncomp = ind = 0; - for (int i = 0; i < N; ++i) - scc[i].clear(); - - // Apply tarjan in every component - for (int i = 0; i < N; ++i) - if (id[i] == -1) - dfs(i); - return ncomp; - } }; diff --git a/algorithms/graph/topological_sort.cpp b/algorithms/graph/topological_sort.cpp index 95a73fe1aa6dea2019908765100be37645e80d45..f9ff6cd6bb5f24454d4454599a8e2ed01ab1947d 100644 --- a/algorithms/graph/topological_sort.cpp +++ b/algorithms/graph/topological_sort.cpp @@ -6,44 +6,44 @@ vector<int> graph[MAX]; struct TopologicalSort { - int N; - stack<int> S; - vector<int> vis; - - TopologicalSort(int N) : - N(N), vis(N) - { init(); } - - void init() { - fill(all(vis), 0); - } - - bool dfs(int x) { - vis[x] = 1; - for (auto i : graph[x]) { - if (vis[i] == 1) return true; - if (!vis[i] && dfs(i)) return true; + int N; + stack<int> S; + vector<int> vis; + + TopologicalSort(int N) : + N(N), vis(N) + { init(); } + + void init() { + fill(all(vis), 0); + } + + bool dfs(int x) { + vis[x] = 1; + for (auto i : graph[x]) { + if (vis[i] == 1) return true; + if (!vis[i] && dfs(i)) return true; + } + + vis[x] = 2; + S.push(x); + return false; } - vis[x] = 2; - S.push(x); - return false; - } - - // Returns whether graph contains cycle - // or not. - bool run(vector<int> &tsort) { - init(); - bool cycle = false; - for (int i = 0; i < N; ++i) - if (!vis[i]) - cycle |= dfs(i); - if (cycle) return true; - - while (!S.empty()) { - tsort.pb(S.top()); - S.pop(); + // Returns whether graph contains cycle + // or not. + bool run(vector<int> &tsort) { + init(); + bool cycle = false; + for (int i = 0; i < N; ++i) + if (!vis[i]) + cycle |= dfs(i); + if (cycle) return true; + + while (!S.empty()) { + tsort.pb(S.top()); + S.pop(); + } + return false; } - return false; - } }; diff --git a/algorithms/graph/travelling_salesman.cpp b/algorithms/graph/travelling_salesman.cpp index c64dce724cfadcb211473478e8a871540890f63d..f6cf6d1c2b332e74b910b265fd98a89682989143 100644 --- a/algorithms/graph/travelling_salesman.cpp +++ b/algorithms/graph/travelling_salesman.cpp @@ -18,28 +18,28 @@ int dp[MAX][1 << MAX]; int graph[MAX][MAX]; struct TSP { - int N; + int N; - TSP(int N) : N(N) - { init(); } + TSP(int N) : N(N) + { init(); } - void init() { mset(dp, -1); } + void init() { mset(dp, -1); } - int solve(int i, int mask) { - if (mask == (1 << N) - 1) - return graph[i][0]; - if (dp[i][mask] != -1) - return dp[i][mask]; + int solve(int i, int mask) { + if (mask == (1 << N) - 1) + return graph[i][0]; + if (dp[i][mask] != -1) + return dp[i][mask]; - int ans = inf; - for (int j = 0; j < N; ++j) - if (!(mask & (1 << j)) && (i != j)) - ans = min(ans, graph[i][j] + - solve(j, mask | (1 << j))); - return dp[i][mask] = ans; - } + int ans = inf; + for (int j = 0; j < N; ++j) + if (!(mask & (1 << j)) && (i != j)) + ans = min(ans, graph[i][j] + + solve(j, mask | (1 << j))); + return dp[i][mask] = ans; + } - int run(int start) { - return solve(start, 1 << start); - } + int run(int start) { + return solve(start, 1 << start); + } }; diff --git a/algorithms/math/big_integer.cpp b/algorithms/math/big_integer.cpp index de456fb68682bb53bfe43949cf00f2554571926a..899fa3646461e4df3bae1dcfcfe68a0c89aa866f 100644 --- a/algorithms/math/big_integer.cpp +++ b/algorithms/math/big_integer.cpp @@ -14,323 +14,323 @@ const int base = 1000000000; const int base_d = 9; struct BigInt { - int sign; - vector<int> num; - - BigInt() : sign(1) {} - BigInt(ll x) { *this = x; } - BigInt(const string &s) { read(s); } - - void operator=(const BigInt &x) { - sign = x.sign; - num = x.num; - } - - void operator=(ll x) { - sign = 1; - if (x < 0) sign = -1, x = -x; - for (; x > 0; x /= base) - pb(x % base); - } - - BigInt operator+(const BigInt &x) const { - if (sign != x.sign) return *this - (-x); - - int carry = 0; - BigInt res = x; - - for (int i = 0; i < max(size(), x.size()) || carry; ++i) { - if (i == (int) res.size()) - res.push_back(0); - - res[i] += carry + (i < size() ? num[i] : 0); - carry = res[i] >= base; - if (carry) res[i] -= base; + int sign; + vector<int> num; + + BigInt() : sign(1) {} + BigInt(i64 x) { *this = x; } + BigInt(const string &s) { read(s); } + + void operator=(const BigInt &x) { + sign = x.sign; + num = x.num; + } + + void operator=(i64 x) { + sign = 1; + if (x < 0) sign = -1, x = -x; + for (; x > 0; x /= base) + pb(x % base); + } + + BigInt operator+(const BigInt &x) const { + if (sign != x.sign) return *this - (-x); + + int carry = 0; + BigInt res = x; + + for (int i = 0; i < max(size(), x.size()) || carry; ++i) { + if (i == (int) res.size()) + res.push_back(0); + + res[i] += carry + (i < size() ? num[i] : 0); + carry = res[i] >= base; + if (carry) res[i] -= base; + } + + return res; + } + + BigInt operator-(const BigInt &x) const { + if (sign != x.sign) return *this + (-x); + if (abs() < x.abs()) return -(x - *this); + + int carry = 0; + BigInt res = *this; + + for (int i = 0; i < x.size() || carry; ++i) { + res[i] -= carry + (i < x.size() ? x[i] : 0); + carry = res[i] < 0; + if (carry) res[i] += base; + } + + res.trim(); + return res; + } + + void operator*=(int x) { + if (x < 0) sign = -sign, x = -x; + + int carry = 0; + for (int i = 0; i < size() || carry; ++i) { + if (i == size()) pb(0); + i64 cur = num[i] * (i64) x + carry; + + carry = (int) (cur / base); + num[i] = (int) (cur % base); + } + + trim(); } - return res; - } + BigInt operator*(int x) const { + BigInt res = *this; + res *= x; + return res; + } - BigInt operator-(const BigInt &x) const { - if (sign != x.sign) return *this + (-x); - if (abs() < x.abs()) return -(x - *this); + friend pair<BigInt, BigInt> divmod(const BigInt &a1, + const BigInt &b1) + { + int norm = base / (b1.back() + 1); + BigInt a = a1.abs() * norm; + BigInt b = b1.abs() * norm; + BigInt q, r; + q.resize(a.size()); + + for (int i = a.size() - 1; i >= 0; i--) { + r *= base; + r += a[i]; + + int s1 = r.size() <= b.size() ? 0 : r[b.size()]; + int s2 = r.size() <= b.size() - 1 ? 0 : r[b.size() - 1]; + int d = ((i64) base * s1 + s2) / b.back(); + + r -= b * d; + while (r < 0) r += b, --d; + q[i] = d; + } + + q.sign = a1.sign * b1.sign; + r.sign = a1.sign; + q.trim(); r.trim(); + + return make_pair(q, r / norm); + } - int carry = 0; - BigInt res = *this; + BigInt operator/(const BigInt &x) const { + return divmod(*this, x).fi; + } - for (int i = 0; i < x.size() || carry; ++i) { - res[i] -= carry + (i < x.size() ? x[i] : 0); - carry = res[i] < 0; - if (carry) res[i] += base; + BigInt operator%(const BigInt &x) const { + return divmod(*this, x).se; } - res.trim(); - return res; - } + void operator/=(int x) { + if (x < 0) sign = -sign, x = -x; - void operator*=(int x) { - if (x < 0) sign = -sign, x = -x; + for (int i = size() - 1, rem = 0; i >= 0; --i) { + i64 cur = num[i] + rem * (i64) base; + num[i] = (int) (cur / x); + rem = (int) (cur % x); + } - int carry = 0; - for (int i = 0; i < size() || carry; ++i) { - if (i == size()) pb(0); - ll cur = num[i] * (ll) x + carry; + trim(); + } - carry = (int) (cur / base); - num[i] = (int) (cur % base); + BigInt operator/(int x) const { + BigInt res = *this; + res /= x; + return res; } - trim(); - } - - BigInt operator*(int x) const { - BigInt res = *this; - res *= x; - return res; - } - - friend pair<BigInt, BigInt> divmod(const BigInt &a1, - const BigInt &b1) - { - int norm = base / (b1.back() + 1); - BigInt a = a1.abs() * norm; - BigInt b = b1.abs() * norm; - BigInt q, r; - q.resize(a.size()); - - for (int i = a.size() - 1; i >= 0; i--) { - r *= base; - r += a[i]; - - int s1 = r.size() <= b.size() ? 0 : r[b.size()]; - int s2 = r.size() <= b.size() - 1 ? 0 : r[b.size() - 1]; - int d = ((ll) base * s1 + s2) / b.back(); - - r -= b * d; - while (r < 0) r += b, --d; - q[i] = d; + int operator%(int x) const { + if (x < 0) x = -x; + + int m = 0; + for (int i = size() - 1; i >= 0; --i) + m = (num[i] + m * (i64) base) % x; + + return m * sign; } - q.sign = a1.sign * b1.sign; - r.sign = a1.sign; - q.trim(); r.trim(); + void operator+=(const BigInt &x) { *this = *this + x; } + void operator-=(const BigInt &x) { *this = *this - x; } + void operator*=(const BigInt &x) { *this = *this * x; } + void operator/=(const BigInt &x) { *this = *this / x; } + + bool operator<(const BigInt &x) const { + if (sign != x.sign) + return sign < x.sign; - return make_pair(q, r / norm); - } + if (size() != x.size()) + return size() * sign < x.size() * x.sign; + + for (int i = size() - 1; i >= 0; i--) + if (num[i] != x[i]) + return num[i] * sign < x[i] * sign; + + return false; + } - BigInt operator/(const BigInt &x) const { - return divmod(*this, x).fi; - } + bool operator>(const BigInt &x) const { + return x < *this; + } + bool operator<=(const BigInt &x) const { + return !(x < *this); + } + bool operator>=(const BigInt &x) const { + return !(*this < x); + } + bool operator==(const BigInt &x) const { + return !(*this < x) && !(x < *this); + } + bool operator!=(const BigInt &x) const { + return *this < x || x < *this; + } - BigInt operator%(const BigInt &x) const { - return divmod(*this, x).se; - } + void trim() { + while (!empty() && !back()) pop_back(); + if (empty()) sign = 1; + } - void operator/=(int x) { - if (x < 0) sign = -sign, x = -x; + bool is_zero() const { + return empty() || (size() == 1 && !num[0]); + } - for (int i = size() - 1, rem = 0; i >= 0; --i) { - ll cur = num[i] + rem * (ll) base; - num[i] = (int) (cur / x); - rem = (int) (cur % x); + BigInt operator-() const { + BigInt res = *this; + res.sign = -sign; + return res; } - trim(); - } - - BigInt operator/(int x) const { - BigInt res = *this; - res /= x; - return res; - } - - int operator%(int x) const { - if (x < 0) x = -x; - - int m = 0; - for (int i = size() - 1; i >= 0; --i) - m = (num[i] + m * (ll) base) % x; - - return m * sign; - } - - void operator+=(const BigInt &x) { *this = *this + x; } - void operator-=(const BigInt &x) { *this = *this - x; } - void operator*=(const BigInt &x) { *this = *this * x; } - void operator/=(const BigInt &x) { *this = *this / x; } - - bool operator<(const BigInt &x) const { - if (sign != x.sign) - return sign < x.sign; - - if (size() != x.size()) - return size() * sign < x.size() * x.sign; - - for (int i = size() - 1; i >= 0; i--) - if (num[i] != x[i]) - return num[i] * sign < x[i] * sign; - - return false; - } - - bool operator>(const BigInt &x) const { - return x < *this; - } - bool operator<=(const BigInt &x) const { - return !(x < *this); - } - bool operator>=(const BigInt &x) const { - return !(*this < x); - } - bool operator==(const BigInt &x) const { - return !(*this < x) && !(x < *this); - } - bool operator!=(const BigInt &x) const { - return *this < x || x < *this; - } - - void trim() { - while (!empty() && !back()) pop_back(); - if (empty()) sign = 1; - } - - bool is_zero() const { - return empty() || (size() == 1 && !num[0]); - } - - BigInt operator-() const { - BigInt res = *this; - res.sign = -sign; - return res; - } - - BigInt abs() const { - BigInt res = *this; - res.sign *= res.sign; - return res; - } - - ll to_long() const { - ll res = 0; - for (int i = size() - 1; i >= 0; i--) - res = res * base + num[i]; - return res * sign; - } - - friend BigInt gcd(const BigInt &a, const BigInt &b) { - return b.is_zero() ? a : gcd(b, a % b); - } - - friend BigInt lcm(const BigInt &a, const BigInt &b) { - return a / gcd(a, b) * b; - } - - void read(const string &s) { - sign = 1; - num.clear(); - - int pos = 0; - while (pos < s.size() && - (s[pos] == '-' || s[pos] == '+')) { - if (s[pos] == '-') - sign = -sign; - ++pos; + BigInt abs() const { + BigInt res = *this; + res.sign *= res.sign; + return res; } - for (int i = s.size() - 1; i >= pos; i -= base_d) { - int x = 0; - for (int j = max(pos, i - base_d + 1); j <= i; j++) - x = x * 10 + s[j] - '0'; - num.push_back(x); + i64 to_long() const { + i64 res = 0; + for (int i = size() - 1; i >= 0; i--) + res = res * base + num[i]; + return res * sign; } - trim(); - } - - friend istream& operator>>(istream &stream, BigInt &v) { - string s; stream >> s; - v.read(s); - return stream; - } - - friend ostream& operator<<(ostream &stream, const BigInt &x) { - if (x.sign == -1) - stream << '-'; - - stream << (x.empty() ? 0 : x.back()); - for (int i = x.size() - 2; i >= 0; --i) - stream << setw(base_d) << setfill('0') << x.num[i]; - - return stream; - } - - static vector<int> convert_base( - const vector<int> &a, - int oldd, int newd) { - vector<ll> p(max(oldd, newd) + 1); - p[0] = 1; - for (int i = 1; i < p.size(); i++) - p[i] = p[i - 1] * 10; - - ll cur = 0; - int curd = 0; - vector<int> res; - - for (int i = 0; i < a.size(); i++) { - cur += a[i] * p[curd]; - curd += oldd; - - while (curd >= newd) { - res.pb(int(cur % p[newd])); - cur /= p[newd]; - curd -= newd; - } + friend BigInt gcd(const BigInt &a, const BigInt &b) { + return b.is_zero() ? a : gcd(b, a % b); } - res.pb((int) cur); - while (!res.empty() && !res.back()) - res.pop_back(); - return res; - } + friend BigInt lcm(const BigInt &a, const BigInt &b) { + return a / gcd(a, b) * b; + } - BigInt operator*(const BigInt &x) const { - vector<int> a6 = convert_base(this->num, base_d, 6); - vector<int> b6 = convert_base(x.num, base_d, 6); + void read(const string &s) { + sign = 1; + num.clear(); + + int pos = 0; + while (pos < s.size() && + (s[pos] == '-' || s[pos] == '+')) { + if (s[pos] == '-') + sign = -sign; + ++pos; + } + + for (int i = s.size() - 1; i >= pos; i -= base_d) { + int x = 0; + for (int j = max(pos, i - base_d + 1); j <= i; j++) + x = x * 10 + s[j] - '0'; + num.push_back(x); + } + + trim(); + } - vector<ll> a(all(a6)); - vector<ll> b(all(b6)); + friend istream& operator>>(istream &stream, BigInt &v) { + string s; stream >> s; + v.read(s); + return stream; + } - while (a.size() < b.size()) a.pb(0); - while (b.size() < a.size()) b.pb(0); - while (a.size() & (a.size() - 1)) - a.pb(0), b.pb(0); + friend ostream& operator<<(ostream &stream, const BigInt &x) { + if (x.sign == -1) + stream << '-'; - vector<ll> c = karatsuba(a, b); + stream << (x.empty() ? 0 : x.back()); + for (int i = x.size() - 2; i >= 0; --i) + stream << setw(base_d) << setfill('0') << x.num[i]; - BigInt res; - int carry = 0; - res.sign = sign * x.sign; + return stream; + } - for (int i = 0; i < c.size(); i++) { - ll cur = c[i] + carry; - res.pb((int) (cur % 1000000)); - carry = (int) (cur / 1000000); + static vector<int> convert_base( + const vector<int> &a, + int oldd, int newd) { + vector<i64> p(max(oldd, newd) + 1); + p[0] = 1; + for (int i = 1; i < p.size(); i++) + p[i] = p[i - 1] * 10; + + i64 cur = 0; + int curd = 0; + vector<int> res; + + for (int i = 0; i < a.size(); i++) { + cur += a[i] * p[curd]; + curd += oldd; + + while (curd >= newd) { + res.pb(int(cur % p[newd])); + cur /= p[newd]; + curd -= newd; + } + } + + res.pb((int) cur); + while (!res.empty() && !res.back()) + res.pop_back(); + return res; } - res.num = convert_base(res.num, 6, base_d); - res.trim(); - return res; - } + BigInt operator*(const BigInt &x) const { + vector<int> a6 = convert_base(this->num, base_d, 6); + vector<int> b6 = convert_base(x.num, base_d, 6); + + vector<i64> a(all(a6)); + vector<i64> b(all(b6)); + + while (a.size() < b.size()) a.pb(0); + while (b.size() < a.size()) b.pb(0); + while (a.size() & (a.size() - 1)) + a.pb(0), b.pb(0); + + vector<i64> c = karatsuba(a, b); + + BigInt res; + int carry = 0; + res.sign = sign * x.sign; + + for (int i = 0; i < c.size(); i++) { + i64 cur = c[i] + carry; + res.pb((int) (cur % 1000000)); + carry = (int) (cur / 1000000); + } + + res.num = convert_base(res.num, 6, base_d); + res.trim(); + return res; + } - // Handles vector operations. - int back() const { return num.back(); } - bool empty() const { return num.empty(); } - size_t size() const { return num.size(); } + // Handles vector operations. + int back() const { return num.back(); } + bool empty() const { return num.empty(); } + size_t size() const { return num.size(); } - void pop_back() { num.pop_back(); } - void resize(int x) { num.resize(x); } - void push_back(int x) { num.push_back(x); } + void pop_back() { num.pop_back(); } + void resize(int x) { num.resize(x); } + void push_back(int x) { num.push_back(x); } - int &operator[](int i) { return num[i]; } - int operator[](int i) const { return num[i]; } + int &operator[](int i) { return num[i]; } + int operator[](int i) const { return num[i]; } }; diff --git a/algorithms/math/binary_exponentiation.cpp b/algorithms/math/binary_exponentiation.cpp index 7c46c08136accebc42eea27cf310b5be11c77337..9ea3f10e375c6c6937a50f9f75a4df4df2bc4375 100644 --- a/algorithms/math/binary_exponentiation.cpp +++ b/algorithms/math/binary_exponentiation.cpp @@ -11,23 +11,24 @@ /// Time: O(log n) /// Space: O(1) -ll bin_mul(ll a, ll b, ll M = MOD) { - ll x = 0; - a %= M; - while (b) { - if (b & 1) x = (x + a) % M; - b >>= 1; - a = (a * 2) % M; - } - return x % M; +i64 bin_mul(i64 a, i64 b, i64 M = MOD) { + i64 x = 0; + a %= M; + while (b) { + if (b & 1) x = (x + a) % M; + b >>= 1; + a = (a * 2) % M; + } + return x % M; } -ll bin_exp(ll a, ll e, ll M = MOD) { - ll x = 1; - while (e) { - if (e & 1) x = bin_mul(x, a, M); - e >>= 1; - a = bin_mul(a, a, M); - } - return x % M; +i64 bin_exp(i64 a, i64 e, i64 M = MOD) { + i64 x = 1; + while (e) { + if (e & 1) + x = (x * a) % M; + e >>= 1; + a = (a * a) % M; + } + return x % M; } diff --git a/algorithms/math/chinese_remainder_theorem.cpp b/algorithms/math/chinese_remainder_theorem.cpp index 8e3f5de86a5a1a0d87be80ef13282ec9bc8cb97c..aae46ccfe31d44de59ed83725071ef6a24dc0689 100644 --- a/algorithms/math/chinese_remainder_theorem.cpp +++ b/algorithms/math/chinese_remainder_theorem.cpp @@ -16,35 +16,35 @@ /// - It is very easy to get overflow, since the $LCM$ is computed from /// all $m_i$, BigInt or Python should be considered if inputs are too large -ll norm(ll a, ll b) { - a %= b; - return (a < 0) ? a + b : a; +i64 norm(i64 a, i64 b) { + a %= b; + return (a < 0) ? a + b : a; } -pair<ll,ll> crt_single(ll a, ll n, ll b, ll m) { - ans_t e = ext_gcd(n, m); +pair<i64,i64> crt_single(i64 a, i64 n, i64 b, i64 m) { + ans_t e = ext_gcd(n, m); - if ((a - b) % e.d != 0) - return {-1,-1}; // No solution + if ((a - b) % e.d != 0) + return {-1,-1}; // No solution - ll lcm = (m/e.d) * n; - ll ans = norm(a + e.x*(b-a) / e.d % (m/e.d)*n, lcm); - return {norm(ans, lcm), lcm}; + i64 lcm = (m/e.d) * n; + i64 ans = norm(a + e.x*(b-a) / e.d % (m/e.d)*n, lcm); + return {norm(ans, lcm), lcm}; } -ll crt(vector<ll> a, vector<ll> m) { - ll ans = a[0]; - ll lcm = m[0]; +i64 crt(vector<i64> a, vector<i64> m) { + i64 ans = a[0]; + i64 lcm = m[0]; - int t = a.size(); - for (int i = 1; i < t; ++i) { - auto ss = crt_single(ans, lcm, a[i], m[i]); - if (ss.fi == -1) - return -1; // No solution + int t = a.size(); + for (int i = 1; i < t; ++i) { + auto ss = crt_single(ans, lcm, a[i], m[i]); + if (ss.fi == -1) + return -1; // No solution - ans = ss.fi; - lcm = ss.se; - } + ans = ss.fi; + lcm = ss.se; + } - return ans; + return ans; } diff --git a/algorithms/math/euler_totient.cpp b/algorithms/math/euler_totient.cpp index 6f407b919f224076db30a048c272125bba915ae0..a9530dc0427872811b95e1c7c16b02294c07afb2 100644 --- a/algorithms/math/euler_totient.cpp +++ b/algorithms/math/euler_totient.cpp @@ -3,17 +3,17 @@ /// Time: O(sqrt{n}) /// Space: O(1) -ll phi(ll n) { - ll ans = n; +i64 phi(i64 n) { + i64 ans = n; - for (ll i = 2; i*i <= n; i++) - if (n % i == 0) { - while (n % i == 0) n /= i; - ans -= ans / i; - } + for (i64 i = 2; i*i <= n; i++) + if (n % i == 0) { + while (n % i == 0) n /= i; + ans -= ans / i; + } - if (n > 1) - ans -= (ans / n); + if (n > 1) + ans -= (ans / n); - return ans; + return ans; } diff --git a/algorithms/math/extended_euclidean.cpp b/algorithms/math/extended_euclidean.cpp index e9dbee732f946057308d037c861afc55fca7b283..7dd4458d4509fc30d43243366e28c00256ed1418 100644 --- a/algorithms/math/extended_euclidean.cpp +++ b/algorithms/math/extended_euclidean.cpp @@ -3,10 +3,10 @@ /// Time: O(log min(a,b)) /// Space: O(1) -struct ans_t { ll x, y, d; }; +struct ans_t { i64 x, y, d; }; -ans_t ext_gcd(ll a, ll b) { - if (a == 0) return {0, 1, b}; - ans_t e = ext_gcd(b % a, a); - return {e.y - (b/a)*e.x, e.x, e.d}; +ans_t ext_gcd(i64 a, i64 b) { + if (a == 0) return {0, 1, b}; + ans_t e = ext_gcd(b % a, a); + return {e.y - (b/a)*e.x, e.x, e.d}; } diff --git a/algorithms/math/fft.cpp b/algorithms/math/fft.cpp index c4f829f8edfe57fcec88abf732dcee2cc26be6f0..b85e4d4ff64b3917ce9ff15a88df5c2b653e5dfc 100644 --- a/algorithms/math/fft.cpp +++ b/algorithms/math/fft.cpp @@ -4,117 +4,117 @@ /// Space: O(N) struct FFT { - struct Complex { - float r, i; + struct Complex { + float r, i; - Complex() : r(0), i(0) {} - Complex(float r, float i) : r(r), i(i) {} + Complex() : r(0), i(0) {} + Complex(float r, float i) : r(r), i(i) {} - Complex operator+(Complex b) { - return Complex(r + b.r, i + b.i); - } + Complex operator+(Complex b) { + return Complex(r + b.r, i + b.i); + } - Complex operator-(Complex b) { - return Complex(r - b.r, i - b.i); - } + Complex operator-(Complex b) { + return Complex(r - b.r, i - b.i); + } - Complex operator*(Complex b) { - return Complex(r*b.r - i*b.i, r*b.i + i*b.r); - } + Complex operator*(Complex b) { + return Complex(r*b.r - i*b.i, r*b.i + i*b.r); + } - Complex operator/(Complex b) { - float div = (b.r * b.r) + (b.i * b.i); - return Complex((r * b.r + i * b.i) / div, - (i * b.r - r * b.i) / div); - } + Complex operator/(Complex b) { + float div = (b.r * b.r) + (b.i * b.i); + return Complex((r * b.r + i * b.i) / div, + (i * b.r - r * b.i) / div); + } - static inline Complex conj(Complex a) { - return Complex(a.r, -a.i); - } - }; + static inline Complex conj(Complex a) { + return Complex(a.r, -a.i); + } + }; - vector<int> rev = {0, 1}; - vector<Complex> roots = {{0, 0}, {1, 0}}; + vector<int> rev = {0, 1}; + vector<Complex> roots = {{0, 0}, {1, 0}}; - // Initializes reversed-bit vector (rev) and - // roots of unity vector (roots) - void init(int nbase) { - rev.resize(1 << nbase); - roots.resize(1 << nbase); + // Initializes reversed-bit vector (rev) and + // roots of unity vector (roots) + void init(int nbase) { + rev.resize(1 << nbase); + roots.resize(1 << nbase); - // Build rev vector - for (int i = 0; i < (1 << nbase); ++i) - rev[i] = (rev[i >> 1] >> 1) + \ - ((i & 1) << (nbase - 1)); + // Build rev vector + for (int i = 0; i < (1 << nbase); ++i) + rev[i] = (rev[i >> 1] >> 1) + \ + ((i & 1) << (nbase - 1)); - // Build roots vector - for (int base = 1; base < nbase; ++base) { - float angle = 2 * M_PI / (1 << (base + 1)); + // Build roots vector + for (int base = 1; base < nbase; ++base) { + float angle = 2 * M_PI / (1 << (base + 1)); - for (int i = 1 << (base - 1); i < (1 << base); ++i) { - float angle_i = angle * (2*i + 1 - (1 << base)); + for (int i = 1 << (base - 1); i < (1 << base); ++i) { + float angle_i = angle * (2*i + 1 - (1 << base)); - roots[i << 1] = roots[i]; - roots[(i << 1) + 1] = Complex(cos(angle_i), - sin(angle_i)); - } + roots[i << 1] = roots[i]; + roots[(i << 1) + 1] = Complex(cos(angle_i), + sin(angle_i)); + } + } } - } - - void fft(vector<Complex> &a) { - int n = a.size(); - for (int i = 0; i < n; ++i) - if (i < rev[i]) - swap(a[i], a[rev[i]]); - - for (int s = 1; s < n; s <<= 1) { - for (int k = 0; k < n; k += (s << 1)) { - for (int j = 0; j < s; ++j) { - Complex z = a[k + j + s] * roots[j + s]; - a[k + j + s] = a[k + j] - z; - a[k + j] = a[k + j] + z; + void fft(vector<Complex> &a) { + int n = a.size(); + + for (int i = 0; i < n; ++i) + if (i < rev[i]) + swap(a[i], a[rev[i]]); + + for (int s = 1; s < n; s <<= 1) { + for (int k = 0; k < n; k += (s << 1)) { + for (int j = 0; j < s; ++j) { + Complex z = a[k + j + s] * roots[j + s]; + a[k + j + s] = a[k + j] - z; + a[k + j] = a[k + j] + z; + } + } } - } } - } - vector<int> multiply(const vector<int> &a, - const vector<int> &b) - { - int nbase, need = a.size() + b.size() + 1; + vector<int> multiply(const vector<int> &a, + const vector<int> &b) + { + int nbase, need = a.size() + b.size() + 1; - for (nbase = 0; (1 << nbase) < need; ++nbase); - init(nbase); + for (nbase = 0; (1 << nbase) < need; ++nbase); + init(nbase); - int size = 1 << nbase; - vector<Complex> fa(size); + int size = 1 << nbase; + vector<Complex> fa(size); - for (int i = 0; i < size; ++i) { - int x = (i < a.size() ? a[i] : 0); - int y = (i < b.size() ? b[i] : 0); - fa[i] = Complex(x, y); - } + for (int i = 0; i < size; ++i) { + int x = (i < a.size() ? a[i] : 0); + int y = (i < b.size() ? b[i] : 0); + fa[i] = Complex(x, y); + } - fft(fa); + fft(fa); - Complex r(0, -0.25 / size); - for (int i = 0; i <= (size >> 1); ++i) { - int j = (size - i) & (size - 1); - Complex z = (fa[j]*fa[j] - conj(fa[i]*fa[i])) * r; + Complex r(0, -0.25 / size); + for (int i = 0; i <= (size >> 1); ++i) { + int j = (size - i) & (size - 1); + Complex z = (fa[j]*fa[j] - conj(fa[i]*fa[i])) * r; - if (i != j) - fa[j] = (fa[i]*fa[i] - conj(fa[j]*fa[j])) * r; + if (i != j) + fa[j] = (fa[i]*fa[i] - conj(fa[j]*fa[j])) * r; - fa[i] = z; - } + fa[i] = z; + } - fft(fa); + fft(fa); - vector<int> res(need); - for (int i = 0; i < need; ++i) - res[i] = fa[i].r + 0.5; + vector<int> res(need); + for (int i = 0; i < need; ++i) + res[i] = fa[i].r + 0.5; - return res; - } + return res; + } }; diff --git a/algorithms/math/gale_shapley.cpp b/algorithms/math/gale_shapley.cpp index f6d38b5285cf3edcfd33e9459461ba1a08377cd8..2e9b24f41f0a3643e7761b96ff6e8137324e0378 100644 --- a/algorithms/math/gale_shapley.cpp +++ b/algorithms/math/gale_shapley.cpp @@ -30,44 +30,44 @@ // Receives matrix of preferences pref[2*N][N] and returns // vector v where v[m] contains preference of the m-th man. vector<int> gale_shapley(const vector<vector<int>> &pref) { - int n = pref[0].size(); - vector<int> w_part(n, -1); - vector<int> m_part(n, -1); - vector<int> start(n, 0); + int n = pref[0].size(); + vector<int> w_part(n, -1); + vector<int> m_part(n, -1); + vector<int> start(n, 0); - while (true) { - int m; - for (m = 0; m < n; ++m) - if (m_part[m] == -1) - break; + while (true) { + int m; + for (m = 0; m < n; ++m) + if (m_part[m] == -1) + break; - if (m == n) break; + if (m == n) break; - for (; start[m] < n && m_part[m] == -1; ++start[m]) { - int w = pref[m][start[m]]; + for (; start[m] < n && m_part[m] == -1; ++start[m]) { + int w = pref[m][start[m]]; - if (w_part[w - n] == -1) { - w_part[w - n] = m; - m_part[m] = w; - } else { - int m1 = w_part[w - n]; - bool pref_m = false; + if (w_part[w - n] == -1) { + w_part[w - n] = m; + m_part[m] = w; + } else { + int m1 = w_part[w - n]; + bool pref_m = false; - for (int j = 0; j < n; ++j) - if (pref[w][j] == m) { - pref_m = true; - break; - } else if (pref[w][j] == m1) - break; + for (int j = 0; j < n; ++j) + if (pref[w][j] == m) { + pref_m = true; + break; + } else if (pref[w][j] == m1) + break; - if (pref_m) { - w_part[w - n] = m; - m_part[m] = w; - m_part[m1] = -1; + if (pref_m) { + w_part[w - n] = m; + m_part[m] = w; + m_part[m1] = -1; + } + } } - } } - } - return m_part; + return m_part; } diff --git a/algorithms/math/karatsuba.cpp b/algorithms/math/karatsuba.cpp index 22f248f54077b8b3523399be23030207000e695b..d18a50055222e3a342eea69b02a83776c808f489 100644 --- a/algorithms/math/karatsuba.cpp +++ b/algorithms/math/karatsuba.cpp @@ -3,46 +3,46 @@ /// Time: O(n^{log(3)}) /// Space: O(n) -vector<ll> karatsuba(const vector<ll> &a, - const vector<ll> &b) +vector<i64> karatsuba(const vector<i64> &a, + const vector<i64> &b) { - int n = a.size(); - vector<ll> res(n + n); - - if (n <= 32) { - for (int i = 0; i < n; i++) - for (int j = 0; j < n; j++) - res[i + j] += a[i] * b[j]; + int n = a.size(); + vector<i64> res(n + n); + + if (n <= 32) { + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) + res[i + j] += a[i] * b[j]; + + return res; + } + + int k = n >> 1; + vector<i64> a1(a.begin(), a.begin() + k); + vector<i64> a2(a.begin() + k, a.end()); + vector<i64> b1(b.begin(), b.begin() + k); + vector<i64> b2(b.begin() + k, b.end()); + + vector<i64> a1b1 = karatsuba(a1, b1); + vector<i64> a2b2 = karatsuba(a2, b2); + + for (int i = 0; i < k; i++) + a2[i] += a1[i]; + for (int i = 0; i < k; i++) + b2[i] += b1[i]; + + vector<i64> r = karatsuba(a2, b2); + for (int i = 0; i < a1b1.size(); i++) + r[i] -= a1b1[i]; + for (int i = 0; i < a2b2.size(); i++) + r[i] -= a2b2[i]; + + for (int i = 0; i < r.size(); i++) + res[i + k] += r[i]; + for (int i = 0; i < a1b1.size(); i++) + res[i] += a1b1[i]; + for (int i = 0; i < a2b2.size(); i++) + res[i + n] += a2b2[i]; return res; - } - - int k = n >> 1; - vector<ll> a1(a.begin(), a.begin() + k); - vector<ll> a2(a.begin() + k, a.end()); - vector<ll> b1(b.begin(), b.begin() + k); - vector<ll> b2(b.begin() + k, b.end()); - - vector<ll> a1b1 = karatsuba(a1, b1); - vector<ll> a2b2 = karatsuba(a2, b2); - - for (int i = 0; i < k; i++) - a2[i] += a1[i]; - for (int i = 0; i < k; i++) - b2[i] += b1[i]; - - vector<ll> r = karatsuba(a2, b2); - for (int i = 0; i < a1b1.size(); i++) - r[i] -= a1b1[i]; - for (int i = 0; i < a2b2.size(); i++) - r[i] -= a2b2[i]; - - for (int i = 0; i < r.size(); i++) - res[i + k] += r[i]; - for (int i = 0; i < a1b1.size(); i++) - res[i] += a1b1[i]; - for (int i = 0; i < a2b2.size(); i++) - res[i + n] += a2b2[i]; - - return res; } diff --git a/algorithms/math/legendre.cpp b/algorithms/math/legendre.cpp index 229c642d5fec72752ccc6348c1284246f683e8da..4d5737fa15ebab214eb1ccca900dd48c6e733afc 100644 --- a/algorithms/math/legendre.cpp +++ b/algorithms/math/legendre.cpp @@ -15,12 +15,12 @@ /// Space: O(1) int legendre(int n, int p) { - int x = 0; + int x = 0; - while (n) { - n /= p; - x += n; - } + while (n) { + n /= p; + x += n; + } - return x; + return x; } diff --git a/algorithms/math/linear_diophantine_equation.cpp b/algorithms/math/linear_diophantine_equation.cpp index e523f2558ea5bfb4693febbb70f0f532e4ebe7b5..1ca814024d249c38c9fa7622c7b4787b328ef741 100644 --- a/algorithms/math/linear_diophantine_equation.cpp +++ b/algorithms/math/linear_diophantine_equation.cpp @@ -14,27 +14,27 @@ /// Space: O(1) struct Diophantine { - int a, b, c, d; - int x0, y0; + int a, b, c, d; + int x0, y0; - bool has_solution; + bool has_solution; - Diophantine(int a, int b, int c) : - a(a), b(b), c(c) - { init(); } + Diophantine(int a, int b, int c) : + a(a), b(b), c(c) + { init(); } - void init() { - ans_t e = ext_gcd(a, b); d = e.d; - if (c % d == 0) { - x0 = e.x * (c / d); - y0 = e.y * (c / d); - has_solution = true; - } else - has_solution = false; - } + void init() { + ans_t e = ext_gcd(a, b); d = e.d; + if (c % d == 0) { + x0 = e.x * (c / d); + y0 = e.y * (c / d); + has_solution = true; + } else + has_solution = false; + } - ii get(int t) { - if (!has_solution) return ii(inf, inf); - return ii(x0 + t * (b / d), y0 - t * (a / d)); - } + p<int> get(int t) { + if (!has_solution) return p<int>(inf, inf); + return p<int>(x0 + t * (b / d), y0 - t * (a / d)); + } }; diff --git a/algorithms/math/matrix.cpp b/algorithms/math/matrix.cpp index e82d439a2ab11bef34a1ad7441e11b575eba65ac..3e761960e14a5f662414d0e75ed9041a10ef9ac6 100644 --- a/algorithms/math/matrix.cpp +++ b/algorithms/math/matrix.cpp @@ -4,29 +4,29 @@ template <typename T> struct Matrix { - int r, c; - vector<vector<T>> m; + int r, c; + vector<vector<T>> m; - Matrix(int r, int c) : r(r), c(c) { - m = vector<vector<T>>(r, vector<T>(c, 0)); - } + Matrix(int r, int c) : r(r), c(c) { + m = vector<vector<T>>(r, vector<T>(c, 0)); + } - Matrix operator*(Matrix a) { - assert(r == a.c && c == a.r); + Matrix operator*(Matrix a) { + assert(r == a.c && c == a.r); - Matrix res(r, c); - for (int i = 0; i < r; i++) - for (int j = 0; j < c; j++) { - res[i][j] = 0; + Matrix res(r, c); + for (int i = 0; i < r; i++) + for (int j = 0; j < c; j++) { + res[i][j] = 0; - for (int k = 0; k < c; k++) - res[i][j] += m[i][k] * a[k][j]; - } + for (int k = 0; k < c; k++) + res[i][j] += m[i][k] * a[k][j]; + } - return res; - } + return res; + } - vector<T> &operator[](int i) { - return m[i]; - } + vector<T> &operator[](int i) { + return m[i]; + } }; diff --git a/algorithms/math/miller_rabin.cpp b/algorithms/math/miller_rabin.cpp index 202ba136c08621ddd3d503c38e574fadebd78fa7..866e927a336d08ee726768edf10b261a7ef427e2 100644 --- a/algorithms/math/miller_rabin.cpp +++ b/algorithms/math/miller_rabin.cpp @@ -3,24 +3,24 @@ /// Time: O(k * log^3 n) /// Space: O(1) -const vector<ll> A = { - 2, 325, 9375, 28178, 450775, 9780504, 1795265022 +const vector<i64> A = { + 2, 325, 9375, 28178, 450775, 9780504, 1795265022 }; -bool is_prime(ll n) { - if (n < 2 || n % 6 % 4 != 1) - return n - 2 < 2; +bool is_prime(i64 n) { + if (n < 2 || n % 6 % 4 != 1) + return n - 2 < 2; - ll s = __builtin_ctzll(n - 1); - ll d = n >> s; + i64 s = __builtin_ctzll(n - 1); + i64 d = n >> s; - for (auto a : A) { - ll p = bin_exp(a, d, n), i = s; - while (p != 1 && p != n - 1 && a % n && i--) - p = bin_mul(p, p, n); - if (p != n - 1 && i != s) - return 0; - } + for (auto a : A) { + i64 p = bin_exp(a, d, n), i = s; + while (p != 1 && p != n - 1 && a % n && i--) + p = bin_mul(p, p, n); + if (p != n - 1 && i != s) + return 0; + } - return 1; + return 1; } diff --git a/algorithms/math/modular_multiplicative_inverse.cpp b/algorithms/math/modular_multiplicative_inverse.cpp index f1024e2609b9619f1497db8afd1104ad768be86e..7d115d3c97c054277ead4b928fa68d7af4665582 100644 --- a/algorithms/math/modular_multiplicative_inverse.cpp +++ b/algorithms/math/modular_multiplicative_inverse.cpp @@ -10,12 +10,12 @@ // Fermat's Little Theorem: Used when m is prime int fermat(int a, int m) { - return bin_exp(a, m - 2); + return bin_exp(a, m - 2); } // Extended Euclidean Algorithm: Used when m // and a are coprime int extended_euclidean(int a, int m) { - ans_t g = ext_gcd(a, m); - return (g.x % m + m) % m; + ans_t g = ext_gcd(a, m); + return (g.x % m + m) % m; } diff --git a/algorithms/math/pollard_rho.cpp b/algorithms/math/pollard_rho.cpp index 99239b17f187c00e82e23cbe001021dc1ad7a853..c5a8b7678fd99c9233d5af103ff60fca982d112d 100644 --- a/algorithms/math/pollard_rho.cpp +++ b/algorithms/math/pollard_rho.cpp @@ -6,30 +6,30 @@ /// Time: O(n^{1/4}) /// Space: O(1) -ll pollard(ll n) { - auto f = [n](ll x) { - return (bin_mul(x, x, n) + 1) % n; - }; +i64 pollard(i64 n) { + auto f = [n](i64 x) { + return (bin_mul(x, x, n) + 1) % n; + }; - if (n % 2 == 0) return 2; + if (n % 2 == 0) return 2; - for (ll i = 2; ; ++i) { - ll x = i, y = f(x), p; - while ((p = __gcd(n + y - x, n)) == 1) - x = f(x), y = f(f(y)); - if (p != n) return p; - } + for (i64 i = 2; ; ++i) { + i64 x = i, y = f(x), p; + while ((p = __gcd(n + y - x, n)) == 1) + x = f(x), y = f(f(y)); + if (p != n) return p; + } } -vector<ll> factor(ll n) { - if (n == 1) return {}; - if (is_prime(n)) // Use Miller-Rabin - return {n}; +vector<i64> factor(i64 n) { + if (n == 1) return {}; + if (is_prime(n)) // Use Miller-Rabin + return {n}; - ll x = pollard(n); - auto l = factor(x); - auto r = factor(n/x); + i64 x = pollard(n); + auto l = factor(x); + auto r = factor(n/x); - l.insert(l.end(), all(r)); - return l; + l.insert(l.end(), all(r)); + return l; } diff --git a/algorithms/math/sieve_of_eratosthenes.cpp b/algorithms/math/sieve_of_eratosthenes.cpp index 07e3c668286d4f9c0e4a4ec3bb87a34f1fa78914..6740d5396da556e57b51754bc29e263f2b371e8b 100644 --- a/algorithms/math/sieve_of_eratosthenes.cpp +++ b/algorithms/math/sieve_of_eratosthenes.cpp @@ -4,17 +4,17 @@ /// Space: O(n) vector<int> sieve(int n) { - vector<int> primes; - vector<int> is_prime(n + 1, 1); + vector<int> primes; + vector<int> is_prime(n + 1, 1); - for (int p = 2; p*p <= n; ++p) - if (is_prime[p]) - for (int i = p*p; i <= n; i += p) - is_prime[i] = false; + for (int p = 2; p*p <= n; ++p) + if (is_prime[p]) + for (int i = p*p; i <= n; i += p) + is_prime[i] = false; - for (int p = 2; p <= n; ++p) - if (is_prime[p]) - primes.pb(p); + for (int p = 2; p <= n; ++p) + if (is_prime[p]) + primes.pb(p); - return primes; + return primes; } diff --git a/algorithms/paradigm/dp_divide_and_conquer.cpp b/algorithms/paradigm/dp_divide_and_conquer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..833356066dc06d2c7c6563be2db03a8da3e412f9 --- /dev/null +++ b/algorithms/paradigm/dp_divide_and_conquer.cpp @@ -0,0 +1,32 @@ +/// Dynamic Programming, Divide and Conquer Optimization +/// +/// Time: O(n * m * log n) +/// Space: O(n * m) + +vector<int> v; +int dp[102][20101]; + +void solve(int g, int i, int j, int l, int r) { + int m = (i + j) / 2; + if (i > j) return; + + p<int> best = { -inf, -1 }; + for (int k = l; k <= min(r, m); ++k) { + mx = max(mx, v[k]); + mn = min(mn, v[k]); + best = max(best, { dp[g-1][k-1] + cost(k, m), k }); + } + + dp[g][m] = best.fi; + solve(g, i, m - 1, l, best.se); + solve(g, m + 1, j, best.se, r); +} + +int calc() { + // setup dp[0][i]; + + for (int i = 1; i <= k; ++i) + solve(i, 1, n, 1, n); + + return dp[k][n]; +} diff --git a/algorithms/paradigm/edit_distance.cpp b/algorithms/paradigm/edit_distance.cpp index e3517d74d4d635623ce37acff41fff34955b0e77..57941840065d5f64fdf4b50adc58757c681002a8 100644 --- a/algorithms/paradigm/edit_distance.cpp +++ b/algorithms/paradigm/edit_distance.cpp @@ -6,18 +6,18 @@ int dp[MAX][MAX]; int edit_distance(string a, string b) { - for (int i = 0; i <= a.size(); ++i) - for (int j = 0; j <= b.size(); ++j) - if (i == 0) - dp[i][j] = j; - else if (j == 0) - dp[i][j] = i; - else if (a[i-1] == b[j-1]) - dp[i][j] = d[i-1][j-1]; - else - dp[i][j] = 1 + min({dp[i][j-1], - dp[i-1][j], - dp[i-1][j-1]}); + for (int i = 0; i <= a.size(); ++i) + for (int j = 0; j <= b.size(); ++j) + if (i == 0) + dp[i][j] = j; + else if (j == 0) + dp[i][j] = i; + else if (a[i-1] == b[j-1]) + dp[i][j] = d[i-1][j-1]; + else + dp[i][j] = 1 + min({dp[i][j-1], + dp[i-1][j], + dp[i-1][j-1]}); - return dp[a.size()][b.size()]; + return dp[a.size()][b.size()]; } diff --git a/algorithms/paradigm/kadane.cpp b/algorithms/paradigm/kadane.cpp index ab38c65a6ec34dec34f056eebc643eb1f2325dab..e8ff1cda5c5b9fd31cb56617cc2e07665824b859 100644 --- a/algorithms/paradigm/kadane.cpp +++ b/algorithms/paradigm/kadane.cpp @@ -4,22 +4,22 @@ /// Space: O(n + m) int kadane(const vector<int> &v, int &start, int &end) { - start = end = 0; - int msf = -inf, meh = 0, s = 0; + start = end = 0; + int msf = -inf, meh = 0, s = 0; - for (int i = 0; i < v.size(); ++i) { - meh += v[i]; + for (int i = 0; i < v.size(); ++i) { + meh += v[i]; - if (msf < meh) { - msf = meh; - start = s, end = i; - } + if (msf < meh) { + msf = meh; + start = s, end = i; + } - if (meh < 0) { - meh = 0; - s = i + 1; + if (meh < 0) { + meh = 0; + s = i + 1; + } } - } - return msf; + return msf; } diff --git a/algorithms/paradigm/lis.cpp b/algorithms/paradigm/lis.cpp index 821903d81f97d21d031041ad31834ba83ff77548..8e54061e26fc18a369a84ec6a28a50f5c787c3bc 100644 --- a/algorithms/paradigm/lis.cpp +++ b/algorithms/paradigm/lis.cpp @@ -4,15 +4,15 @@ /// Space: O(n) int lis(vector<int> v) { - vector<int> lis(v.size()); lis[0] = 1; + vector<int> lis(v.size()); lis[0] = 1; - for (int i = 1; i < v.size(); ++i) { - lis[i] = 1; + for (int i = 1; i < v.size(); ++i) { + lis[i] = 1; - for (int j = 0; j < i; ++j) - if (v[i] > v[j] && lis[i] < lis[j] + 1) - lis[i] = lis[j] + 1; - } + for (int j = 0; j < i; ++j) + if (v[i] > v[j] && lis[i] < lis[j] + 1) + lis[i] = lis[j] + 1; + } - return *max_element(all(lis)); + return *max_element(all(lis)); } diff --git a/algorithms/paradigm/longest_common_subsequence.cpp b/algorithms/paradigm/longest_common_subsequence.cpp index acffd3895d7b91ada8d1f590f0efb37b63976f95..70979a1f314f0c7701c1324f9a9be0ba4fe45795 100644 --- a/algorithms/paradigm/longest_common_subsequence.cpp +++ b/algorithms/paradigm/longest_common_subsequence.cpp @@ -6,33 +6,33 @@ int dp[MAX][MAX]; string lcs(string a, string b) { - for (int i = 0; i <= a.size(); ++i) { - for (int j = 0; j <= b.size(); ++j) { - if (i == 0 || j == 0) - dp[i][j] = 0; - else if (a[i - 1] == b[j - 1]) - dp[i][j] = dp[i - 1][j - 1] + 1; - else - dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); + for (int i = 0; i <= a.size(); ++i) { + for (int j = 0; j <= b.size(); ++j) { + if (i == 0 || j == 0) + dp[i][j] = 0; + else if (a[i - 1] == b[j - 1]) + dp[i][j] = dp[i - 1][j - 1] + 1; + else + dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); + } } - } - // The size is already at dp[n][m], now the common - // subsequence is retrieved: + // The size is already at dp[n][m], now the common + // subsequence is retrieved: - int idx = dp[a.size()][b.size()]; - string ans(idx, ' '); + int idx = dp[a.size()][b.size()]; + string ans(idx, ' '); - int i = a.size(), j = b.size(); - while (i > 0 && j > 0) { - if (a[i - 1] == b[ j - 1]) { - ans[idx - 1] = a[i - 1]; - i--, j--, idx--; - } else if (dp[i - 1][j] > dp[i][j - 1]) - i--; - else - j--; - } + int i = a.size(), j = b.size(); + while (i > 0 && j > 0) { + if (a[i - 1] == b[ j - 1]) { + ans[idx - 1] = a[i - 1]; + i--, j--, idx--; + } else if (dp[i - 1][j] > dp[i][j - 1]) + i--; + else + j--; + } - return ans; + return ans; } diff --git a/algorithms/paradigm/ternary_search.cpp b/algorithms/paradigm/ternary_search.cpp index 457f407c35cdb56aca1443c253ecdf5d972917ac..c6b5c724c39ae949c33bb8250a0b4d1abb15a6e8 100644 --- a/algorithms/paradigm/ternary_search.cpp +++ b/algorithms/paradigm/ternary_search.cpp @@ -14,20 +14,20 @@ // Maximum of f: comp = greater<T>() template <typename T, class F = function<T(T)>> T ternary_search(T l, T r, F f, function<bool(T,T)> comp) { - T rt, lt; + T rt, lt; - for (int i = 0; i < 500; ++i) { - if (fabs(r - l) < EPS) - return (l + r) / 2; + for (int i = 0; i < 500; ++i) { + if (fabs(r - l) < EPS) + return (l + r) / 2; - lt = (r - l) / 3 + l; - rt = ((r - l) * 2) / 3 + l; + lt = (r - l) / 3 + l; + rt = ((r - l) * 2) / 3 + l; - if (comp(f(lt), f(rt))) - l = lt; - else - r = rt; - } + if (comp(f(lt), f(rt))) + l = lt; + else + r = rt; + } - return (l + r) / 2; + return (l + r) / 2; } diff --git a/algorithms/string/aho_corasick.cpp b/algorithms/string/aho_corasick.cpp index b6aaa36efb1d1677d6661a76380789f539c66f53..f9ad5fbec156e726cebff80f2efa5323778d2159 100644 --- a/algorithms/string/aho_corasick.cpp +++ b/algorithms/string/aho_corasick.cpp @@ -11,107 +11,107 @@ /// - Match might not find all occurences when repeated strings are given (fix with map) struct AhoCorasick { - struct Node { - vector<int> words; - map<char,int> next; - int fail, cnt, hei, occ; + struct Node { + vector<int> words; + map<char,int> next; + int fail, cnt, hei, occ; - Node() : fail(0), cnt(0), hei(0), occ(-1) {} - int has(char i) { return next.count(i); } - int &operator[](char i) { return next[i]; } - }; - - vector<int> top; - vector<Node> trie; + Node() : fail(0), cnt(0), hei(0), occ(-1) {} + int has(char i) { return next.count(i); } + int &operator[](char i) { return next[i]; } + }; - AhoCorasick(const vector<string> &v) { - trie.pb(Node()); - build(v); - top = preprocess(); - } + vector<int> top; + vector<Node> trie; - int insert(const string &s) { - int n = 0; - for (int i = 0; i < s.size(); n = trie[n][s[i]], ++i) - if (!trie[n].has(s[i])) { - trie[n][s[i]] = trie.size(); - trie[n].hei = i + 1; + AhoCorasick(const vector<string> &v) { trie.pb(Node()); - } - return n; - } - - void build(const vector<string> &v) { - for (int i = 0; i < v.size(); ++i) { - int n = insert(v[i]); - trie[n].words.pb(i); + build(v); + top = preprocess(); } - } - inline int suffix(int v, char c) { - while (v != 0 && !trie[v].has(c)) v = trie[v].fail; - if (trie[v].has(c)) v = trie[v][c]; - return v; - } + int insert(const string &s) { + int n = 0; + for (int i = 0; i < s.size(); n = trie[n][s[i]], ++i) + if (!trie[n].has(s[i])) { + trie[n][s[i]] = trie.size(); + trie[n].hei = i + 1; + trie.pb(Node()); + } + return n; + } - vector<int> preprocess() { - vector<int> Q = { 0 }; - for (int i = 0; i != Q.size(); ++i) { - int u = Q[i]; - for (auto j : trie[u].next) { - int &v = trie[j.se].fail; - if (u) { - v = suffix(trie[u].fail, j.fi); - trie[j.se].occ = trie[v].words.size() ? v : trie[v].occ; - } else { - v = trie[u].fail; - trie[j.se].occ = -1; + void build(const vector<string> &v) { + for (int i = 0; i < v.size(); ++i) { + int n = insert(v[i]); + trie[n].words.pb(i); } - Q.pb(j.se); - } } - return Q; - } - // Returns vector with indices of the strings occuring at - // least once in pattern p - vector<int> match(const string &p) { - int u = 0; - for (auto i : p) { - u = suffix(u, i); - trie[u].cnt++; + inline int suffix(int v, char c) { + while (v != 0 && !trie[v].has(c)) v = trie[v].fail; + if (trie[v].has(c)) v = trie[v][c]; + return v; } - for (int i = top.size() - 1; i >= 0; --i) - trie[trie[top[i]].fail].cnt += trie[top[i]].cnt; - vector<int> ans; - for (auto &i : trie) - if (i.cnt && i.words.size()) - for (auto j : i.words) ans.pb(j); + vector<int> preprocess() { + vector<int> Q = { 0 }; + for (int i = 0; i != Q.size(); ++i) { + int u = Q[i]; + for (auto j : trie[u].next) { + int &v = trie[j.se].fail; + if (u) { + v = suffix(trie[u].fail, j.fi); + trie[j.se].occ = trie[v].words.size() ? v : trie[v].occ; + } else { + v = trie[u].fail; + trie[j.se].occ = -1; + } + Q.pb(j.se); + } + } + return Q; + } - sort(all(ans)); - return ans; - } + // Returns vector with indices of the strings occuring at + // least once in pattern p + vector<int> match(const string &p) { + int u = 0; + for (auto i : p) { + u = suffix(u, i); + trie[u].cnt++; + } + for (int i = top.size() - 1; i >= 0; --i) + trie[trie[top[i]].fail].cnt += trie[top[i]].cnt; - // Returns all occurences of strings in p, where ans[i].fi - // is the indice of the string and ans[i].se is where in p - // does the string start - vector<ii> match_all(const string &p) { - int u = 0; - vector<ii> ans; - for (int i = 0; i < p.size(); ++i) { - u = suffix(u, p[i]); - for (auto j : trie[u].words) - ans.pb({j, i - trie[u].hei + 1}); + vector<int> ans; + for (auto &i : trie) + if (i.cnt && i.words.size()) + for (auto j : i.words) ans.pb(j); - int x = u; - while (trie[x].occ != -1) { - x = trie[x].occ; - for (auto j : trie[x].words) - ans.pb({j, i - trie[x].hei + 1}); - } + sort(all(ans)); + return ans; + } + + // Returns all occurences of strings in p, where ans[i].fi + // is the indice of the string and ans[i].se is where in p + // does the string start + vector<p<int>> match_all(const string &p) { + int u = 0; + vector<p<int>> ans; + for (int i = 0; i < p.size(); ++i) { + u = suffix(u, p[i]); + for (auto j : trie[u].words) + ans.pb({j, i - trie[u].hei + 1}); + + int x = u; + while (trie[x].occ != -1) { + x = trie[x].occ; + for (auto j : trie[x].words) + ans.pb({j, i - trie[x].hei + 1}); + } + } + sort(all(ans)); + return ans; } - sort(all(ans)); - return ans; - } }; diff --git a/algorithms/string/booth.cpp b/algorithms/string/booth.cpp index 19a684e232044c0d8fb7588eee1d3c2958284bb2..8b53794a91ce62a1a9cad45973b8947a0e94f3cc 100644 --- a/algorithms/string/booth.cpp +++ b/algorithms/string/booth.cpp @@ -12,31 +12,31 @@ // Maximal: func = greater<char>() // Minimal: func = less<char>() string booth(string s, function<bool(char,char)> func) { - string S = s + s; - vector<int> f(S.size(), -1); + string S = s + s; + vector<int> f(S.size(), -1); - int k = 0; - for (int j = 1; j < S.size(); ++j) { - char sj = S[j]; - int i = f[j - k - 1]; + int k = 0; + for (int j = 1; j < S.size(); ++j) { + char sj = S[j]; + int i = f[j - k - 1]; - while (i != -1 && sj != S[k+i+1]) { - if (func(sj, S[k + i + 1])) - k = j - i - 1; - i = f[i]; - } + while (i != -1 && sj != S[k+i+1]) { + if (func(sj, S[k + i + 1])) + k = j - i - 1; + i = f[i]; + } - if (sj != S[k+i+1]) { - if (func(sj, S[k])) - k = j; + if (sj != S[k+i+1]) { + if (func(sj, S[k])) + k = j; - f[j-k] = -1; - } else - f[j-k] = i + 1; - } + f[j-k] = -1; + } else + f[j-k] = i + 1; + } - string ans(s.size(), 0); - for (int i = 0; i < s.size(); ++i) - ans[i] = S[k+i]; - return ans; + string ans(s.size(), 0); + for (int i = 0; i < s.size(); ++i) + ans[i] = S[k+i]; + return ans; } diff --git a/algorithms/string/kmp.cpp b/algorithms/string/kmp.cpp index 85ff29fe4643394e09614081a7efae5d1d28e687..9db20e790cc43f4617dc3532195f5871faebde0a 100644 --- a/algorithms/string/kmp.cpp +++ b/algorithms/string/kmp.cpp @@ -8,34 +8,34 @@ /// Status: Tested (URI2350,UVA10679) struct KMP { - string patt; - vector<int> pi; + string patt; + vector<int> pi; - KMP(string patt) : - patt(patt), pi(patt.size()) - { preprocess(); } + KMP(string patt) : + patt(patt), pi(patt.size()) + { preprocess(); } - void preprocess() { - pi[0] = 0; - for (int i = 1, j = 0; i < patt.size(); ++i) { - while (j > 0 && patt[i] != patt[j]) - j = pi[j - 1]; + void preprocess() { + pi[0] = 0; + for (int i = 1, j = 0; i < patt.size(); ++i) { + while (j > 0 && patt[i] != patt[j]) + j = pi[j - 1]; - if (patt[i] == patt[j]) j++; - pi[i] = j; + if (patt[i] == patt[j]) j++; + pi[i] = j; + } } - } - void search(const string &txt) { - for (int i = 0, j = 0; i < txt.size(); ++i) { - while (j > 0 && txt[i] != patt[j]) - j = pi[j - 1]; + void search(const string &txt) { + for (int i = 0, j = 0; i < txt.size(); ++i) { + while (j > 0 && txt[i] != patt[j]) + j = pi[j - 1]; - if (txt[i] == patt[j]) j++; - if (j == patt.size()) { - cout << "Pattern found at " << (i - j) << ende; - j = pi[j - 1]; - } + if (txt[i] == patt[j]) j++; + if (j == patt.size()) { + cout << "Pattern found at " << (i - j) << ende; + j = pi[j - 1]; + } + } } - } }; diff --git a/algorithms/string/z-function.cpp b/algorithms/string/z-function.cpp index c1e6c789b7dc83e3ebe921a1debfd60e8d745284..3744a23504f6d0449d7846f681c704cc3f70de2a 100644 --- a/algorithms/string/z-function.cpp +++ b/algorithms/string/z-function.cpp @@ -4,22 +4,22 @@ /// Space: O(n) vector<int> z_function(string s) { - int n = (int) s.length(); - vector<int> z(n); + int n = (int) s.length(); + vector<int> z(n); - int l = 0, r = 0; - for (int i = 1; i < n; ++i) { - if (i <= r) - z[i] = min(r - i + 1, z[i - l]); + int l = 0, r = 0; + for (int i = 1; i < n; ++i) { + if (i <= r) + z[i] = min(r - i + 1, z[i - l]); - while (i + z[i] < n && s[z[i]] == s[i + z[i]]) - z[i]++; + while (i + z[i] < n && s[z[i]] == s[i + z[i]]) + z[i]++; - if (i + z[i] - 1 > r) { - l = i; - r = i + z[i] - 1; + if (i + z[i] - 1 > r) { + l = i; + r = i + z[i] - 1; + } } - } - return z; + return z; } diff --git a/algorithms/structure/avl.cpp b/algorithms/structure/avl.cpp index 5746c131f9022abdee76a23ff08f2b45bf5136bf..32ba0dd56d236c607fea7dfeaede73f003feb1a6 100644 --- a/algorithms/structure/avl.cpp +++ b/algorithms/structure/avl.cpp @@ -4,83 +4,83 @@ /// Space: O(n) struct AVL { - struct Node { - int key, height; - Node *left, *right; + struct Node { + int key, height; + Node *left, *right; - Node(int k) : - key(k), height(1), - left(nullptr), right(nullptr) - {} + Node(int k) : + key(k), height(1), + left(nullptr), right(nullptr) + {} - static int get_height(Node *n) { - return (n == nullptr) ? 0 : n->height; - } + static int get_height(Node *n) { + return (n == nullptr) ? 0 : n->height; + } - void fix_state() { - height = max(Node::get_height(left), - Node::get_height(left)) + 1; - } + void fix_state() { + height = max(Node::get_height(left), + Node::get_height(left)) + 1; + } + + int get_balance() { + return Node::get_height(left) - + Node::get_height(right); + } + }; - int get_balance() { - return Node::get_height(left) - - Node::get_height(right); + Node *root; + + AVL() : root(nullptr) {} + + void insert(int key) { + root = insert(root, key); } - }; - - Node *root; - - AVL() : root(nullptr) {} - - void insert(int key) { - root = insert(root, key); - } - -private: - - Node *rotate_right(Node *n) { - Node *aux1 = n->left; - Node *aux2 = aux1->right; - aux1->right = n; aux1->fix_state(); - n->left = aux2; n->fix_state(); - return aux1; - } - - Node *rotate_left(Node *n) { - Node *aux1 = n->right; - Node *aux2 = aux1->left; - aux1->left = n; aux1->fix_state(); - n->right = aux2; n->fix_state(); - return aux1; - } - - Node *insert(Node *n, int key) { - if (n == nullptr) { - Node *new_node = new Node(key); - if (root == nullptr) root = new_node; - return new_node; + + private: + + Node *rotate_right(Node *n) { + Node *aux1 = n->left; + Node *aux2 = aux1->right; + aux1->right = n; aux1->fix_state(); + n->left = aux2; n->fix_state(); + return aux1; } - if (key < n->key) - n->left = insert(n->left, key); - else - n->right = insert(n->right, key); - - int balance = n->get_balance(); - n->fix_state(); - - if (balance > 1 && key < n->left->key) { - return rotate_right(n); - } else if (balance < -1 && key > n->right->key) { - return rotate_left(n); - } else if (balance > 1 && key > n->left->key) { - n->left = rotate_left(n->left); - return rotate_right(n); - } else if (balance < -1 && key < n->right->key) { - n->right = rotate_right(n->right); - return rotate_left(n); + Node *rotate_left(Node *n) { + Node *aux1 = n->right; + Node *aux2 = aux1->left; + aux1->left = n; aux1->fix_state(); + n->right = aux2; n->fix_state(); + return aux1; } - return n; - } + Node *insert(Node *n, int key) { + if (n == nullptr) { + Node *new_node = new Node(key); + if (root == nullptr) root = new_node; + return new_node; + } + + if (key < n->key) + n->left = insert(n->left, key); + else + n->right = insert(n->right, key); + + int balance = n->get_balance(); + n->fix_state(); + + if (balance > 1 && key < n->left->key) { + return rotate_right(n); + } else if (balance < -1 && key > n->right->key) { + return rotate_left(n); + } else if (balance > 1 && key > n->left->key) { + n->left = rotate_left(n->left); + return rotate_right(n); + } else if (balance < -1 && key < n->right->key) { + n->right = rotate_right(n->right); + return rotate_left(n); + } + + return n; + } }; diff --git a/algorithms/structure/bit.cpp b/algorithms/structure/bit.cpp index 3b20716fae8ea4ed35d09a96471f709b5ded8ddf..6230c5828b198165142d0ac84f925e6dfc46c6a3 100644 --- a/algorithms/structure/bit.cpp +++ b/algorithms/structure/bit.cpp @@ -6,20 +6,20 @@ /// Space: O(n) struct BIT { - int N; - vector<int> tree; + int N; + vector<int> tree; - BIT(int N) : N(N), tree(N, 0) {} + BIT(int N) : N(N), tree(N, 0) {} - int query(int idx) { - int sum = 0; - for (; idx > 0; idx -= (idx & -idx)) - sum += tree[idx]; - return sum; - } + int query(int idx) { + int sum = 0; + for (; idx > 0; idx -= (idx & -idx)) + sum += tree[idx]; + return sum; + } - void update(int idx, int val) { - for (; idx < N; idx += (idx & -idx)) - tree[idx] += val; - } + void update(int idx, int val) { + for (; idx < N; idx += (idx & -idx)) + tree[idx] += val; + } }; diff --git a/algorithms/structure/bit2d.cpp b/algorithms/structure/bit2d.cpp index e02ba49c632e3c06548e45cf84eb26fa8d595549..cafba95b98e9849e4eb3eb13021cbb95298b7e62 100644 --- a/algorithms/structure/bit2d.cpp +++ b/algorithms/structure/bit2d.cpp @@ -8,23 +8,24 @@ /// Status: Tested (MCAIRO) struct BIT2D { - int N, M; - vector<vector<int>> tree; + int N, M; + vector<vector<int>> tree; - BIT2D(int N, int M) : N(N), M(M), - tree(N, vector<int>(M, 0)) {} + BIT2D(int N, int M) : N(N), M(M), + tree(N, vector<int>(M, 0)) + {} - int query(int idx, int idy) { - int sum = 0; - for (; idx > 0; idx -= (idx & -idx)) - for (int m = idy; m > 0; m -= (m & -m)) - sum += tree[idx][m]; - return sum; - } + int query(int idx, int idy) { + int sum = 0; + for (; idx > 0; idx -= (idx & -idx)) + for (int m = idy; m > 0; m -= (m & -m)) + sum += tree[idx][m]; + return sum; + } - void update(int idx, int idy, int val) { - for (; idx < N; idx += (idx & -idx)) - for (int m = idy; m < M; m += (m & -m)) - tree[idx][m] += val; - } + void update(int idx, int idy, int val) { + for (; idx < N; idx += (idx & -idx)) + for (int m = idy; m < M; m += (m & -m)) + tree[idx][m] += val; + } }; diff --git a/algorithms/structure/bitmask.cpp b/algorithms/structure/bitmask.cpp index 59d2a928ef475f0e99b40694bfb1626102c77dad..1137e14587d4f82364ee0727714ed80ccb527931 100644 --- a/algorithms/structure/bitmask.cpp +++ b/algorithms/structure/bitmask.cpp @@ -4,36 +4,36 @@ /// Space: O(1) struct Bitmask { - ll state; + i64 state; - Bitmask(ll state) : - state(state) {} + Bitmask(i64 state) : + state(state) {} - void set(int pos) { - state |= (1 << pos); - } + void set(int pos) { + state |= (1 << pos); + } - void set_all(int n) { - state = (1 << n) - 1; - } + void set_all(int n) { + state = (1 << n) - 1; + } - void unset(int pos) { - state &= ~(1 << pos); - } + void unset(int pos) { + state &= ~(1 << pos); + } - void unset_all() { - state = 0; - } + void unset_all() { + state = 0; + } - int get(int pos) { - return state & (1 << pos); - } + int get(int pos) { + return state & (1 << pos); + } - void toggle(int pos) { - state ^= (1 << pos); - } + void toggle(int pos) { + state ^= (1 << pos); + } - int least_significant_one() { - return state & (-state); - } + int least_significant_one() { + return state & (-state); + } }; diff --git a/algorithms/structure/disjoint_set.cpp b/algorithms/structure/disjoint_set.cpp index 67a7594bf32fb7e916463f69228846f877afaaac..256ceeebfe9584f2c8b7a8e318855bbea2be0dc3 100644 --- a/algorithms/structure/disjoint_set.cpp +++ b/algorithms/structure/disjoint_set.cpp @@ -7,33 +7,33 @@ /// Space: O(n) struct DisjointSet { - int N; - vector<int> rnk, par, siz; + int N; + vector<int> rnk, par, siz; - DisjointSet(int N) : - N(N), rnk(N), par(N), siz(N) - { init(); } + DisjointSet(int N) : + N(N), rnk(N), par(N), siz(N) + { init(); } - void init() { - iota(all(par), 0); - fill(all(rnk), 0); - fill(all(siz), 1); - } + void init() { + iota(all(par), 0); + fill(all(rnk), 0); + fill(all(siz), 1); + } - int find_set(int x) { - if (par[x] != x) - par[x] = find_set(par[x]); - return par[x]; - } + int find_set(int x) { + if (par[x] != x) + par[x] = find_set(par[x]); + return par[x]; + } - void union_set(int x, int y) { - x = find_set(x); - y = find_set(y); + void union_set(int x, int y) { + x = find_set(x); + y = find_set(y); - if (x == y) return; - if (rnk[x] < rnk[y]) swap(x, y); - if (rnk[x] == rnk[y]) rnk[x]++; - par[y] = x; - siz[x] += siz[y]; - } + if (x == y) return; + if (rnk[x] < rnk[y]) swap(x, y); + if (rnk[x] == rnk[y]) rnk[x]++; + par[y] = x; + siz[x] += siz[y]; + } }; diff --git a/algorithms/structure/hash_function.cpp b/algorithms/structure/hash_function.cpp index 4497b534301f69c8702ed2f259af88c328776a44..b26f1b68f65126a24d24062f65bdd4dd6af04e29 100644 --- a/algorithms/structure/hash_function.cpp +++ b/algorithms/structure/hash_function.cpp @@ -10,19 +10,19 @@ /// Space: O(n) struct CustomHash { - static uint64_t splitmix64(uint64_t x) { - x += 0x9e3779b97f4a7c15; - x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; - x = (x ^ (x >> 27)) * 0x94d049bb133111eb; - return x ^ (x >> 31); - } + static uint64_t splitmix64(uint64_t x) { + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } - size_t operator()(uint64_t x) const { - static const uint64_t FIXED_RANDOM = chrono::steady_clock::now() - .time_since_epoch() - .count(); - return splitmix64(x + FIXED_RANDOM); - } + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now() + .time_since_epoch() + .count(); + return splitmix64(x + FIXED_RANDOM); + } }; -unordered_map<ll,int,CustomHash> M; +unordered_map<i64,int,CustomHash> M; diff --git a/algorithms/structure/lazy_segment_tree.cpp b/algorithms/structure/lazy_segment_tree.cpp index 758c47dc43f69c0f6e827527901156766c233d27..fa39bd24a0808f04a9d2f64d25bd271649d29aa4 100644 --- a/algorithms/structure/lazy_segment_tree.cpp +++ b/algorithms/structure/lazy_segment_tree.cpp @@ -17,71 +17,71 @@ int N; template <typename T, class F = function<T(const T&, const T&)>> struct LazySegmentTree { - F func; - T id = T(); - vector<T> tree, lazy; - - LazySegmentTree(F func) : - func(func), tree(MAX*4, 0), lazy(MAX*4, 0) {} - - void build(const vector<T> &v, - int node = 1, int l = 0, int r = N - 1) - { - if (l > r) return; - - if (l == r) - tree[node] = v[l]; - else { - int m = (l + r) / 2; - build(v, left(node), l, m); - build(v, right(node), m + 1, r); - tree[node] = func(tree[left(node)], tree[right(node)]); + F func; + T id = T(); + vector<T> tree, lazy; + + LazySegmentTree(F func) : + func(func), tree(MAX*4, 0), lazy(MAX*4, 0) {} + + void build(const vector<T> &v, + int node = 1, int l = 0, int r = N - 1) + { + if (l > r) return; + + if (l == r) + tree[node] = v[l]; + else { + int m = (l + r) / 2; + build(v, left(node), l, m); + build(v, right(node), m + 1, r); + tree[node] = func(tree[left(node)], tree[right(node)]); + } } - } - void push(int node, int l, int r, T val) { - tree[node] += (r - l + 1) * val; + void push(int node, int l, int r, T val) { + tree[node] += (r - l + 1) * val; - if (l != r) { - lazy[left(node)] += val; - lazy[right(node)] += val; - } - - lazy[node] = 0; - } - - void update(int i, int j, T val, - int node = 1, int l = 0, int r = N - 1) - { - if (lazy[node] != 0) - push(node, l, r, lazy[node]); + if (l != r) { + lazy[left(node)] += val; + lazy[right(node)] += val; + } - if (l > r || l > j || r < i) return; + lazy[node] = 0; + } - if (i <= l && r <= j) - push(node, l, r, val); - else { - int m = (l + r) / 2; - update(i, j, val, left(node), l, m); - update(i, j, val, right(node), m + 1, r); - tree[node] = func(tree[left(node)], tree[right(node)]); + void update(int i, int j, T val, + int node = 1, int l = 0, int r = N - 1) + { + if (lazy[node] != 0) + push(node, l, r, lazy[node]); + + if (l > r || l > j || r < i) return; + + if (i <= l && r <= j) + push(node, l, r, val); + else { + int m = (l + r) / 2; + update(i, j, val, left(node), l, m); + update(i, j, val, right(node), m + 1, r); + tree[node] = func(tree[left(node)], tree[right(node)]); + } } - } - T query(int i, int j, - int node = 1, int l = 0, int r = N - 1) - { - if (l > r || l > j || r < i) return id; + T query(int i, int j, + int node = 1, int l = 0, int r = N - 1) + { + if (l > r || l > j || r < i) return id; - if (lazy[node]) - push(node, l, r, lazy[node]); + if (lazy[node]) + push(node, l, r, lazy[node]); - if (l >= i && r <= j) - return tree[node]; + if (l >= i && r <= j) + return tree[node]; - int m = (l + r) / 2; - T q1 = query(i, j, left(node), l, m); - T q2 = query(i, j, right(node), m + 1, r); - return func(q1, q2); - } + int m = (l + r) / 2; + T q1 = query(i, j, left(node), l, m); + T q2 = query(i, j, right(node), m + 1, r); + return func(q1, q2); + } }; diff --git a/algorithms/structure/mo_algorithm.cpp b/algorithms/structure/mo_algorithm.cpp index 64803b3910424fb04a3d24c885615a14264dd5da..e73eb3122f0962206d0c6516b84c7f24d495fbe3 100644 --- a/algorithms/structure/mo_algorithm.cpp +++ b/algorithms/structure/mo_algorithm.cpp @@ -7,39 +7,39 @@ /// - Remember to implement add, remove, and get\_ans functions. struct Query { - int l, r, idx; + int l, r, idx; }; vector<int> mos_algorithm(vector<Query> Q) { - int blk_size = (int) sqrt(v.size() + 0.0) + 1; + int blk_size = (int) sqrt(v.size() + 0.0) + 1; - vector<int> ans(Q.size()); - sort(all(Q), [](Query a, Query b) { - return ii(a.l / blk_size, a.r) < ii(b.l / blk_size, b.r); - }); + vector<int> ans(Q.size()); + sort(all(Q), [](Query a, Query b) { + return p<int>(a.l / blk_size, a.r) < p<int>(b.l / blk_size, b.r); + }); - int curr_l = 0, curr_r = -1; + int curr_l = 0, curr_r = -1; - for (auto q : Q) { - while (curr_l > q.l) { - curr_l--; - add(curr_l); - } - while (curr_r < q.r) { - curr_r++; - add(curr_r); - } - while (curr_l < q.l) { - remove(curr_l); - curr_l++; - } - while (curr_r > q.r) { - remove(curr_r); - curr_r--; - } + for (auto q : Q) { + while (curr_l > q.l) { + curr_l--; + add(curr_l); + } + while (curr_r < q.r) { + curr_r++; + add(curr_r); + } + while (curr_l < q.l) { + remove(curr_l); + curr_l++; + } + while (curr_r > q.r) { + remove(curr_r); + curr_r--; + } - ans[q.idx] = get_ans(); - } + ans[q.idx] = get_ans(); + } - return ans; + return ans; } diff --git a/algorithms/structure/policy_tree.cpp b/algorithms/structure/policy_tree.cpp index 9e06d9b8d4b0e2ca627bb863c440c90ed1569bc1..92850f865fbce4c0e5529e76ef11cb3b23736f48 100644 --- a/algorithms/structure/policy_tree.cpp +++ b/algorithms/structure/policy_tree.cpp @@ -15,21 +15,20 @@ using namespace __gnu_pbds; template <typename T> -using ordered_set = - tree<T, null_type, less<T>, rb_tree_tag, - tree_order_statistics_node_update>; +using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, + tree_order_statistics_node_update>; void operations() { - ordered_set S; + ordered_set S; - S.insert(x); - S.erase(x); + S.insert(x); + S.erase(x); - // Return iordered_set terator to the k-th largest element - // (counting from zero) - int pos = *S.find_by_order(k); + // Return iordered_set terator to the k-th largest element + // (counting from zero) + int pos = *S.find_by_order(k); - // Return the number of items strictly smaller - // than x - int ord = S.order_of_key(x) + // Return the number of items strictly smaller + // than x + int ord = S.order_of_key(x) } diff --git a/algorithms/structure/segment_tree.cpp b/algorithms/structure/segment_tree.cpp index 9f388480225a16fbb50725b5d287dcc3b6ac96fd..edc5f26b0a46ddf29cf7307d131628ee0ec9ead0 100644 --- a/algorithms/structure/segment_tree.cpp +++ b/algorithms/structure/segment_tree.cpp @@ -10,34 +10,34 @@ template<typename T, class F = function<T(T,T)>> struct SegmentTree { - int N; - F func; - T id = T(); - vector<T> tree; + int N; + F func; + T id = T(); + vector<T> tree; - SegmentTree(int N, F func) : - N(N), func(func), tree(N*2, id) - {} + SegmentTree(int N, F func) : + N(N), func(func), tree(N*2, id) + {} - void build(const vector<T> &v) { - for (int i = 0; i < N; ++i) - tree[N + i] = v[i]; - for (int i = N - 1; i > 0; --i) - tree[i] = func(tree[i*2], tree[i*2+1]); - } + void build(const vector<T> &v) { + for (int i = 0; i < N; ++i) + tree[N + i] = v[i]; + for (int i = N - 1; i > 0; --i) + tree[i] = func(tree[i*2], tree[i*2+1]); + } - void update(int i, T x) { - tree[i += N] = x; - for (i /= 2; i > 0; i /= 2) - tree[i] = func(tree[i*2], tree[i*2+1]); - } + void update(int i, T x) { + tree[i += N] = x; + for (i /= 2; i > 0; i /= 2) + tree[i] = func(tree[i*2], tree[i*2+1]); + } - T query(int i, int j) { - T left = id, right = id; - for (i += N, j += N; i < j; i /= 2, j /= 2) { - if (i & 1) left = func(left, tree[i++]); - if (j & 1) right = func(right, tree[--j]); + T query(int i, int j) { + T left = id, right = id; + for (i += N, j += N; i < j; i /= 2, j /= 2) { + if (i & 1) left = func(left, tree[i++]); + if (j & 1) right = func(right, tree[--j]); + } + return func(left, right); } - return func(left, right); - } }; diff --git a/algorithms/structure/segment_tree_2d.cpp b/algorithms/structure/segment_tree_2d.cpp index e749c57e0b114de4e0d3af5ba05ddde7b8681596..f3ad859624c7b10f3d16db6f9272ac48981db147 100644 --- a/algorithms/structure/segment_tree_2d.cpp +++ b/algorithms/structure/segment_tree_2d.cpp @@ -16,102 +16,102 @@ int N, M; template<typename T, class F = function<T(T,T)>> struct SegmentTree2D { - using matrix<T> = vector<vector<T>>; - - F func; - T id = T(); - matrix<T> tree; - - SegmentTree2D(F func) : - tree(4*MAX, vector<T>(4*MAX, 0)), - func(func) {} - - void build_row(const matrix<T> &mat, - int ni, int li, int ri, - int nj = 1, int lj = 0, int rj = M - 1) - { - if (lj == rj) { - if (li == ri) - tree[ni][nj] = mat[li][lj]; - else - tree[ni][nj] = func(tree[left(ni)][nj], tree[right(ni)][nj]); - } else { - int m = (lj + rj) / 2; - build_row(mat, ni, li, ri, left(nj), lj, m); - build_row(mat, ni, li, ri, right(nj), m+1, rj); - tree[ni][nj] = func(tree[ni][left(nj)], tree[ni][right(nj)]); + using matrix<T> = vector<vector<T>>; + + F func; + T id = T(); + matrix<T> tree; + + SegmentTree2D(F func) : + tree(4*MAX, vector<T>(4*MAX, 0)), + func(func) {} + + void build_row(const matrix<T> &mat, + int ni, int li, int ri, + int nj = 1, int lj = 0, int rj = M - 1) + { + if (lj == rj) { + if (li == ri) + tree[ni][nj] = mat[li][lj]; + else + tree[ni][nj] = func(tree[left(ni)][nj], tree[right(ni)][nj]); + } else { + int m = (lj + rj) / 2; + build_row(mat, ni, li, ri, left(nj), lj, m); + build_row(mat, ni, li, ri, right(nj), m+1, rj); + tree[ni][nj] = func(tree[ni][left(nj)], tree[ni][right(nj)]); + } } - } - - void build(const matrix<T> &mat, - int ni = 1, int li = 0, int ri = N - 1) - { - if (li != ri) { - int m = (li + ri) / 2; - build(mat, left(ni), li, m); - build(mat, right(ni), m+1, ri); + + void build(const matrix<T> &mat, + int ni = 1, int li = 0, int ri = N - 1) + { + if (li != ri) { + int m = (li + ri) / 2; + build(mat, left(ni), li, m); + build(mat, right(ni), m+1, ri); + } + build_row(mat, ni, li, ri); } - build_row(mat, ni, li, ri); - } - - T query_row(int j1, int j2, int i, - int nj = 1, int lj = 0, int rj = M - 1) - { - if (lj > rj || lj > j2 || rj < j1) return id; - - if (j1 <= lj && rj <= j2) - return tree[i][nj]; - - int m = (lj + rj) / 2; - T q1 = query_row(j1, j2, i, left(nj), lj, m); - T q2 = query_row(j1, j2, i, right(nj), m + 1, rj); - return func(q1, q2); - } - - T query(int i1, int j1, int i2, int j2, - int ni = 1, int li = 0, int ri = N - 1) - { - if (li > ri || li > i2 || ri < i1) return id; - - if (i1 <= li && ri <= i2) - return query_row(j1, j2, ni); - - int m = (li + ri) / 2; - T q1 = query(i1, j1, i2, j2, left(ni), li, m); - T q2 = query(i1, j1, i2, j2, right(ni), m + 1, ri); - return func(q1, q2); - } - - void update_row(int i, int j, T val, - int ni, int li, int ri, - int nj = 1, int lj = 0, int rj = M - 1) - { - if (lj > rj || lj > j || rj < j) return; - - if (lj == rj) { - if (li == ri) - tree[ni][nj] = val; - else - tree[ni][nj] = func(tree[left(ni)][nj], tree[right(ni)][nj]); - } else { - int m = (lj + rj) / 2; - update_row(i, j, val, ni, li, ri, left(nj), lj, m); - update_row(i, j, val, ni, li, ri, right(nj), m+1, rj); - tree[ni][nj] = func(tree[ni][left(nj)], tree[ni][right(nj)]); + + T query_row(int j1, int j2, int i, + int nj = 1, int lj = 0, int rj = M - 1) + { + if (lj > rj || lj > j2 || rj < j1) return id; + + if (j1 <= lj && rj <= j2) + return tree[i][nj]; + + int m = (lj + rj) / 2; + T q1 = query_row(j1, j2, i, left(nj), lj, m); + T q2 = query_row(j1, j2, i, right(nj), m + 1, rj); + return func(q1, q2); } - } - void update(int i, int j, T val, - int ni = 1, int li = 0, int ri = N - 1) - { - if (li > ri || li > i || ri < i) return; + T query(int i1, int j1, int i2, int j2, + int ni = 1, int li = 0, int ri = N - 1) + { + if (li > ri || li > i2 || ri < i1) return id; + + if (i1 <= li && ri <= i2) + return query_row(j1, j2, ni); - if (li != ri) { - int m = (li + ri) / 2; - update(i, j, val, left(ni), li, m); - update(i, j, val, right(ni), m+1, ri); + int m = (li + ri) / 2; + T q1 = query(i1, j1, i2, j2, left(ni), li, m); + T q2 = query(i1, j1, i2, j2, right(ni), m + 1, ri); + return func(q1, q2); } - update_row(i, j, val, ni, li, ri); - } + void update_row(int i, int j, T val, + int ni, int li, int ri, + int nj = 1, int lj = 0, int rj = M - 1) + { + if (lj > rj || lj > j || rj < j) return; + + if (lj == rj) { + if (li == ri) + tree[ni][nj] = val; + else + tree[ni][nj] = func(tree[left(ni)][nj], tree[right(ni)][nj]); + } else { + int m = (lj + rj) / 2; + update_row(i, j, val, ni, li, ri, left(nj), lj, m); + update_row(i, j, val, ni, li, ri, right(nj), m+1, rj); + tree[ni][nj] = func(tree[ni][left(nj)], tree[ni][right(nj)]); + } + } + + void update(int i, int j, T val, + int ni = 1, int li = 0, int ri = N - 1) + { + if (li > ri || li > i || ri < i) return; + + if (li != ri) { + int m = (li + ri) / 2; + update(i, j, val, left(ni), li, m); + update(i, j, val, right(ni), m+1, ri); + } + + update_row(i, j, val, ni, li, ri); + } }; diff --git a/algorithms/structure/sparse_table.cpp b/algorithms/structure/sparse_table.cpp index 3d08456b08952ff570515a00e7a61e6e40c281a7..8ea29f06d1ae811fc32ef2d33abfb3cfdfe7705b 100644 --- a/algorithms/structure/sparse_table.cpp +++ b/algorithms/structure/sparse_table.cpp @@ -13,33 +13,33 @@ template <typename T, class F = function<T(T,T)>> struct SparseTable { - F func; - int N; - vector<T> log; - vector<vector<T>> table; + F func; + int N; + vector<T> log; + vector<vector<T>> table; - SparseTable(const vector<T> &v, F func) : - N(v.size()), - log(N + 1), - table(N, vector<T>(LOG+1)), - func(func) - { preprocess(v); } + SparseTable(const vector<T> &v, F func) : + N(v.size()), + log(N + 1), + table(N, vector<T>(LOG+1)), + func(func) + { preprocess(v); } - void preprocess(const vector<T> &v) { - log[1] = 0; - for (int i = 2; i <= N; ++i) - log[i] = log[i >> 1] + 1; + void preprocess(const vector<T> &v) { + log[1] = 0; + for (int i = 2; i <= N; ++i) + log[i] = log[i >> 1] + 1; - for (int i = 0; i < N; ++i) - table[i][0] = v[i]; + for (int i = 0; i < N; ++i) + table[i][0] = v[i]; - for (int j = 1; j <= LOG; ++j) - for (int i = 0; i + (1 << j) <= N; ++i) - table[i][j] = func(table[i][j-1], table[i+(1<<(j-1))][j-1]); - } + for (int j = 1; j <= LOG; ++j) + for (int i = 0; i + (1 << j) <= N; ++i) + table[i][j] = func(table[i][j-1], table[i+(1<<(j-1))][j-1]); + } - T query(int l, int r) { - int j = log[r - l + 1]; - return func(table[l][j], table[r - (1<<j) + 1][j]); - } + T query(int l, int r) { + int j = log[r - l + 1]; + return func(table[l][j], table[r - (1<<j) + 1][j]); + } }; diff --git a/algorithms/structure/sqrt_decomposition.cpp b/algorithms/structure/sqrt_decomposition.cpp index b84d1a5e77a89cb2fa64eabfc9e39f1bd47e065e..001d7685684ab0e86b0f82d4745111d2f8629104 100644 --- a/algorithms/structure/sqrt_decomposition.cpp +++ b/algorithms/structure/sqrt_decomposition.cpp @@ -7,45 +7,45 @@ /// Space: O(n) struct SqrtDecomposition { - int blk_size; - vector<int> v, blk; - - SqrtDecomposition(vector<int> v) : - v(v), blk(v.size()) - { init(); } - - void init() { - build(); - } - - void update(int idx, int val) { - blk[idx / blk_size] += val - v[idx]; - v[idx] = val; - } - - int query(int l, int r) { - int ans = 0; - int cl = l/blk_size, cr = r/blk_size; - - if (cl == cr) { - for (int i = l; i <= r; ++i) - ans += v[i]; - } else { - for (int i = l, end=(cl+1)*blk_size-1; i <= end; ++i) - ans += v[i]; - for (int i = cl+1; i <= cr - 1; ++i) - ans += blk[i]; - for (int i = cr*blk_size; i <= r; ++i) - ans += v[i]; + int blk_size; + vector<int> v, blk; + + SqrtDecomposition(vector<int> v) : + v(v), blk(v.size()) + { init(); } + + void init() { + build(); + } + + void update(int idx, int val) { + blk[idx / blk_size] += val - v[idx]; + v[idx] = val; } - return ans; - } + int query(int l, int r) { + int ans = 0; + int cl = l/blk_size, cr = r/blk_size; + + if (cl == cr) { + for (int i = l; i <= r; ++i) + ans += v[i]; + } else { + for (int i = l, end=(cl+1)*blk_size-1; i <= end; ++i) + ans += v[i]; + for (int i = cl+1; i <= cr - 1; ++i) + ans += blk[i]; + for (int i = cr*blk_size; i <= r; ++i) + ans += v[i]; + } + + return ans; + } - void build() { - int n = v.size(); - blk_size = (int) sqrt(n + 0.0) + 1; - for (int i = 0; i < n; ++i) - blk[idx / blk_size] += v[i]; - } + void build() { + int n = v.size(); + blk_size = (int) sqrt(n + 0.0) + 1; + for (int i = 0; i < n; ++i) + blk[idx / blk_size] += v[i]; + } }; diff --git a/algorithms/structure/trie.cpp b/algorithms/structure/trie.cpp index 626a677f5fdfa7a434be03ed410a7aaa88e492aa..d1847bdcafdf3dadb2aa072768dc2e6937a6705b 100644 --- a/algorithms/structure/trie.cpp +++ b/algorithms/structure/trie.cpp @@ -10,57 +10,57 @@ template <typename T> struct Trie { - int states; + int states; - vector<int> ending; - vector<vector<int>> trie; + vector<int> ending; + vector<vector<int>> trie; - // Number of words (N) and number of letters per word - // (M), and number of letters in alphabet (alph). - Trie(int N, int M, int alph) : - ending(N * M), - trie(N * M, vector<int>(alph)) - { init(); } + // Number of words (N) and number of letters per word + // (M), and number of letters in alphabet (alph). + Trie(int N, int M, int alph) : + ending(N * M), + trie(N * M, vector<int>(alph)) + { init(); } - void init() { - states = 0; - for (auto &i : trie) - fill(all(i), -1); - } + void init() { + states = 0; + for (auto &i : trie) + fill(all(i), -1); + } - int len(T x) { - if (constexpr(is_same_v<T,int>)) - return 32; - return x.size(); - } + int len(T x) { + if (constexpr(is_same_v<T,int>)) + return 32; + return x.size(); + } - int idx(T x) { - if (constexpr(is_same_v<T,int>)) - return !!(x & (1 << i)); - return x[i] - 'a'; - } + int idx(T x) { + if (constexpr(is_same_v<T,int>)) + return !!(x & (1 << i)); + return x[i] - 'a'; + } - void insert(T x) { - int node = 0; + void insert(T x) { + int node = 0; - for (int i = 0; i < len(x); ++i) { - if (trie[node][idx(x, i)] == -1) - trie[node][idx(x, i)] = ++states; - node = trie[node][idx(x, i)]; + for (int i = 0; i < len(x); ++i) { + if (trie[node][idx(x, i)] == -1) + trie[node][idx(x, i)] = ++states; + node = trie[node][idx(x, i)]; + } + + ending[node] = true; } - ending[node] = true; - } + bool search(T x) { + int node = 0; - bool search(T x) { - int node = 0; + for (int i = 0; i < len(x); ++i) { + node = trie[node][idx(x, i)]; + if (node == -1) + return false; + } - for (int i = 0; i < len(x); ++i) { - node = trie[node][idx(x, i)]; - if (node == -1) - return false; + return ending[node]; } - - return ending[node]; - } }; diff --git a/caderno.pdf b/caderno.pdf index 6f3e97c4cb78c2cd65a23c9b20a96dbf2f81cf99..31252e48245ad63bc2ff1352b55c4eb533a5d77f 100644 Binary files a/caderno.pdf and b/caderno.pdf differ diff --git a/contests/Cadernaveis/BALE11.cpp b/contests/Cadernaveis/BALE11.cpp index 2dbcd8a9aef47ce2e39261b3900c655b301fbb53..89f65fc16ef3e50652f6272b483b72846c569a41 100644 --- a/contests/Cadernaveis/BALE11.cpp +++ b/contests/Cadernaveis/BALE11.cpp @@ -27,33 +27,33 @@ int v[MAX]; int tree[MAX]; int query(int idx) { - int sum = 0; - for (; idx > 0; idx -= (idx & -idx)) - sum += tree[idx]; + int sum = 0; + for (; idx > 0; idx -= (idx & -idx)) + sum += tree[idx]; - return sum; + return sum; } void update(int idx, int val) { - for (; idx <= MAX; idx += (idx & -idx)) - tree[idx] += val; + for (; idx <= MAX; idx += (idx & -idx)) + tree[idx] += val; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n; - cin >> n; - for (int i = 0; i < n; ++i) - cin >> v[i]; - - int ans = 0; - for (int i = 0; i < n; ++i) { - ans += query(n - v[i] + 1); - update(n - v[i] + 1, 1); - } - - cout << ans << '\n'; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int n; + cin >> n; + for (int i = 0; i < n; ++i) + cin >> v[i]; + + int ans = 0; + for (int i = 0; i < n; ++i) { + ans += query(n - v[i] + 1); + update(n - v[i] + 1, 1); + } + + cout << ans << '\n'; + return 0; } diff --git a/contests/Cadernaveis/CAVALOS.cpp b/contests/Cadernaveis/CAVALOS.cpp index d3407170de1f7ece04ac3e33b2545f0db62c3a46..80dcfef30b2320dbc3e45e82c99ec91bdbea6124 100644 --- a/contests/Cadernaveis/CAVALOS.cpp +++ b/contests/Cadernaveis/CAVALOS.cpp @@ -30,74 +30,74 @@ int graph[MAX][MAX], rg[MAX][MAX]; bool cont[MAX]; bool path(int s, int t) { - cont[s] = true; - if (s == t) - return true; + cont[s] = true; + if (s == t) + return true; - for (int i = 0; i < N; ++i) - if (!cont[i] && rg[s][i]) { - par[i] = s; + for (int i = 0; i < N; ++i) + if (!cont[i] && rg[s][i]) { + par[i] = s; - if (path(i, t)) - return true; - } + if (path(i, t)) + return true; + } - return false; + return false; } int ford_fulkerson(int s, int t) { - int ans = 0; - par[s] = -1; + int ans = 0; + par[s] = -1; - mset(cont, 0); - memcpy(rg, graph, sizeof(graph)); + mset(cont, 0); + memcpy(rg, graph, sizeof(graph)); - while (path(s, t)) { - int flow = inf; + while (path(s, t)) { + int flow = inf; - for (int i = t; par[i] != -1; i = par[i]) - flow = min(flow, rg[par[i]][i]); + for (int i = t; par[i] != -1; i = par[i]) + flow = min(flow, rg[par[i]][i]); - for (int i = t; par[i] != -1; i = par[i]) { - rg[par[i]][i] -= flow; - rg[i][par[i]] += flow; - } + for (int i = t; par[i] != -1; i = par[i]) { + rg[par[i]][i] -= flow; + rg[i][par[i]] += flow; + } - ans += flow; - mset(cont, 0); - } + ans += flow; + mset(cont, 0); + } - return ans; + return ans; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, m, k, cas = 1; - while (cin >> n >> m >> k) { - mset(graph, 0); - - N = MAX; - int s = 0, t = MAX-1; - for (int i = 1; i <= n; ++i) { - int c; cin >> c; - graph[i + 120][t] = c; - } - - for (int i = 0; i < k; ++i) { - int x, y; cin >> x >> y; - graph[y][x + 120] = 1; + ios::sync_with_stdio(0); + cin.tie(0); + + int n, m, k, cas = 1; + while (cin >> n >> m >> k) { + mset(graph, 0); + + N = MAX; + int s = 0, t = MAX-1; + for (int i = 1; i <= n; ++i) { + int c; cin >> c; + graph[i + 120][t] = c; + } + + for (int i = 0; i < k; ++i) { + int x, y; cin >> x >> y; + graph[y][x + 120] = 1; + } + + for (int i = 1; i <= m; ++i) + graph[s][i] = 1; + + cout << "Instancia " << cas++ << ende; + cout << ford_fulkerson(s, t) << ende; + cout << ende; } - - for (int i = 1; i <= m; ++i) - graph[s][i] = 1; - - cout << "Instancia " << cas++ << ende; - cout << ford_fulkerson(s, t) << ende; - cout << ende; - } - return 0; + return 0; } diff --git a/contests/Cadernaveis/CF342E.cpp b/contests/Cadernaveis/CF342E.cpp index 746231ae1ab08722222e87ea80c3c099ac742a39..382794c072c002176961157bf68042b2cdad0cf9 100644 --- a/contests/Cadernaveis/CF342E.cpp +++ b/contests/Cadernaveis/CF342E.cpp @@ -1,190 +1,190 @@ /// Xenia and Tree #include <bits/stdc++.h> - + #define MAX 101010 #define EPS 1e-6 #define MOD 1000000007 #define inf 0x3f3f3f3f #define llinf 0x3f3f3f3f3f3f3f3f - + #define fi first #define se second #define pb push_back #define ende '\n' - + #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() #define mset(x, y) memset(&x, (y), sizeof(x)) - + using namespace std; - + using ll = long long; using ii = pair<int,int>; - + #define MAXLOG 20 - + vector<ii> graph[MAX]; - + struct LCA { - vector<int> h; - vector<vector<int>> par, cost; - - LCA(int N) : - h(N), - par(N, vector<int>(MAXLOG)), - cost(N, vector<int>(MAXLOG)) - { - init(); - } - - void init() { - for (auto &i : par) - fill(all(i), -1); - for (auto &i : cost) - fill(all(i), 0); - dfs(0); - } - - inline int op(int a, int b) { - return a + b; - } - - void dfs(int v, int p = -1, int c = 0) { - par[v][0] = p; - cost[v][0] = c; - - if (p != -1) - h[v] = h[p] + 1; - - for (int i = 1; i < MAXLOG; ++i) - if (par[v][i - 1] != -1) { - par[v][i] = par[par[v][i - 1]][i - 1]; - cost[v][i] = op(cost[v][i], op(cost[par[v][i-1]][i-1], cost[v][i-1])); - } - - for (auto u : graph[v]) - if (p != u.fi) - dfs(u.fi, v, u.se); - } - - int query(int p, int q) { - int ans = 0; // * - - if (h[p] < h[q]) - swap(p, q); - - for (int i = MAXLOG - 1; i >= 0; --i) - if (par[p][i] != -1 && h[par[p][i]] >= h[q]) { - ans = op(ans, cost[p][i]); - p = par[p][i]; - } - - if (p == q) { - return ans; + vector<int> h; + vector<vector<int>> par, cost; + + LCA(int N) : + h(N), + par(N, vector<int>(MAXLOG)), + cost(N, vector<int>(MAXLOG)) + { + init(); + } + + void init() { + for (auto &i : par) + fill(all(i), -1); + for (auto &i : cost) + fill(all(i), 0); + dfs(0); + } + + inline int op(int a, int b) { + return a + b; + } + + void dfs(int v, int p = -1, int c = 0) { + par[v][0] = p; + cost[v][0] = c; + + if (p != -1) + h[v] = h[p] + 1; + + for (int i = 1; i < MAXLOG; ++i) + if (par[v][i - 1] != -1) { + par[v][i] = par[par[v][i - 1]][i - 1]; + cost[v][i] = op(cost[v][i], op(cost[par[v][i-1]][i-1], cost[v][i-1])); + } + + for (auto u : graph[v]) + if (p != u.fi) + dfs(u.fi, v, u.se); + } + + int query(int p, int q) { + int ans = 0; // * + + if (h[p] < h[q]) + swap(p, q); + + for (int i = MAXLOG - 1; i >= 0; --i) + if (par[p][i] != -1 && h[par[p][i]] >= h[q]) { + ans = op(ans, cost[p][i]); + p = par[p][i]; + } + + if (p == q) { + return ans; + } + + for (int i = MAXLOG - 1; i >= 0; --i) + if (par[p][i] != -1 && par[p][i] != par[q][i]) { + ans = op(ans, op(cost[p][i], cost[q][i])); + p = par[p][i]; + q = par[q][i]; + } + + if (p == q) return ans; + else return op(ans, op(cost[p][0], cost[q][0])); } - - for (int i = MAXLOG - 1; i >= 0; --i) - if (par[p][i] != -1 && par[p][i] != par[q][i]) { - ans = op(ans, op(cost[p][i], cost[q][i])); - p = par[p][i]; - q = par[q][i]; - } - - if (p == q) return ans; - else return op(ans, op(cost[p][0], cost[q][0])); - } }; - + struct CentroidDecomposition { - vector<int> par, size, marked; - - CentroidDecomposition(int N) : - par(N), size(N), marked(N) - { - init(); - } - - void init() { - fill(all(marked), 0); - build(0, -1); - } - - void build(int x, int p) { - int n = dfs(x, -1); - int centroid = get_centroid(x, -1, n); - marked[centroid] = 1; - - par[centroid] = p; - - for (auto i : graph[centroid]) { - if (!marked[i.fi]) - build(i.fi, centroid); + vector<int> par, size, marked; + + CentroidDecomposition(int N) : + par(N), size(N), marked(N) + { + init(); + } + + void init() { + fill(all(marked), 0); + build(0, -1); + } + + void build(int x, int p) { + int n = dfs(x, -1); + int centroid = get_centroid(x, -1, n); + marked[centroid] = 1; + + par[centroid] = p; + + for (auto i : graph[centroid]) { + if (!marked[i.fi]) + build(i.fi, centroid); + } + } + + int dfs(int x, int p) { + size[x] = 1; + for (auto i : graph[x]) + if (i.fi != p && !marked[i.fi]) + size[x] += dfs(i.fi, x); + + return size[x]; + } + + int get_centroid(int x, int p, int n) { + for (auto i : graph[x]) + if (i.fi != p && size[i.fi] > n / 2 && !marked[i.fi]) + return get_centroid(i.fi, x, n); + return x; + } + + int operator[](int i) { + return par[i]; } - } - - int dfs(int x, int p) { - size[x] = 1; - for (auto i : graph[x]) - if (i.fi != p && !marked[i.fi]) - size[x] += dfs(i.fi, x); - - return size[x]; - } - - int get_centroid(int x, int p, int n) { - for (auto i : graph[x]) - if (i.fi != p && size[i.fi] > n / 2 && !marked[i.fi]) - return get_centroid(i.fi, x, n); - return x; - } - - int operator[](int i) { - return par[i]; - } }; - + int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, m; cin >> n >> m; - vector<int> ans(n, inf); - - for (int i = 0; i < n - 1; ++i) { - int a, b; cin >> a >> b; - a--, b--; - graph[a].pb(ii(b, 1)); - graph[b].pb(ii(a, 1)); - } - - LCA lca(n); - CentroidDecomposition cd(n); - - int p = 0; - while (p != -1) { - ans[p] = min(ans[p], lca.query(0, p)); - p = cd[p]; - } - - for (int i = 0; i < m; ++i) { - int a, b; cin >> a >> b; - b--; - if (a == 1) { - int p = b; - while (p != -1) { - ans[p] = min(ans[p], lca.query(b, p)); - p = cd[p]; - } - } else { - int p = b, res = inf; - while (p != -1) { - res = min(res, lca.query(b, p) + ans[p]); + ios::sync_with_stdio(0); + cin.tie(0); + + int n, m; cin >> n >> m; + vector<int> ans(n, inf); + + for (int i = 0; i < n - 1; ++i) { + int a, b; cin >> a >> b; + a--, b--; + graph[a].pb(ii(b, 1)); + graph[b].pb(ii(a, 1)); + } + + LCA lca(n); + CentroidDecomposition cd(n); + + int p = 0; + while (p != -1) { + ans[p] = min(ans[p], lca.query(0, p)); p = cd[p]; - } - cout << res << ende; } - } - - return 0; + + for (int i = 0; i < m; ++i) { + int a, b; cin >> a >> b; + b--; + if (a == 1) { + int p = b; + while (p != -1) { + ans[p] = min(ans[p], lca.query(b, p)); + p = cd[p]; + } + } else { + int p = b, res = inf; + while (p != -1) { + res = min(res, lca.query(b, p) + ans[p]); + p = cd[p]; + } + cout << res << ende; + } + } + + return 0; } diff --git a/contests/Cadernaveis/DESCULPA.cpp b/contests/Cadernaveis/DESCULPA.cpp index 3996dc212873d786c91a878b00b93d0e6b98250f..a23e095367c36e38822e434d1c5fc5cc659e78f9 100644 --- a/contests/Cadernaveis/DESCULPA.cpp +++ b/contests/Cadernaveis/DESCULPA.cpp @@ -1,7 +1,7 @@ /// Pedido de Desculpas #include <bits/stdc++.h> - + #define MAX 1010 #define EPS 1e-6 #define MOD 1000000007 @@ -22,31 +22,31 @@ using namespace std; typedef long long ll; typedef pair<int,int> ii; - + int dp[60][MAX]; int v[MAX], w[MAX]; - + int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int c, f, cas = 1; - while (cin >> c >> f && (c || f)) { - memset(dp, 0, sizeof dp); - for (int i = 1; i <= f; ++i) - cin >> w[i] >> v[i]; - - for (int i = 1; i <= f; ++i) - for (int j = 0; j <= c; ++j) - if (j >= w[i]) - dp[i][j] = max(dp[i-1][j], dp[i-1][j - w[i]] + v[i]); - else - dp[i][j] = dp[i-1][j]; - - cout << "Teste " << cas << ende; - cout << dp[f][c] << ende << ende; - cas++; - } - - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int c, f, cas = 1; + while (cin >> c >> f && (c || f)) { + memset(dp, 0, sizeof dp); + for (int i = 1; i <= f; ++i) + cin >> w[i] >> v[i]; + + for (int i = 1; i <= f; ++i) + for (int j = 0; j <= c; ++j) + if (j >= w[i]) + dp[i][j] = max(dp[i-1][j], dp[i-1][j - w[i]] + v[i]); + else + dp[i][j] = dp[i-1][j]; + + cout << "Teste " << cas << ende; + cout << dp[f][c] << ende << ende; + cas++; + } + + return 0; } diff --git a/contests/Cadernaveis/EASUDOKU.cpp b/contests/Cadernaveis/EASUDOKU.cpp index 70af254db00c764610319abcf102730d5441d238..e945d08a32ac360f0c18fc0e0b3ea33e98f2f5c5 100644 --- a/contests/Cadernaveis/EASUDOKU.cpp +++ b/contests/Cadernaveis/EASUDOKU.cpp @@ -25,58 +25,58 @@ vector<vector<int>> mat, filled; vector<int> init = {0, 0, 0, 3, 3, 3, 6, 6, 6}; int check(int r, int c) { - int ans = 0; - for (int i = 0; i < 9; ++i) ans |= (1 << mat[r][i]); - for (int i = 0; i < 9; ++i) ans |= (1 << mat[i][c]); + int ans = 0; + for (int i = 0; i < 9; ++i) ans |= (1 << mat[r][i]); + for (int i = 0; i < 9; ++i) ans |= (1 << mat[i][c]); - for (int i = init[r]; i < init[r] + 3; ++i) - for (int j = init[c]; j < init[c] + 3; ++j) - ans |= (1 << mat[i][j]); + for (int i = init[r]; i < init[r] + 3; ++i) + for (int j = init[c]; j < init[c] + 3; ++j) + ans |= (1 << mat[i][j]); - return ans; + return ans; } bool solve(int i, int j) { - if (filled[i][j]) { - if (i == 8 && j == 8) return true; - else return solve(i + (j == 8), (j + 1) % 9); - } - - int poss = check(i, j); - for (int k = 1; k <= 9; ++k) { - if ((poss & (1 << k)) == 0) { - mat[i][j] = k; - if (i == 8 && j == 8) return true; - if (solve(i + (j == 8), (j + 1) % 9)) return true; - mat[i][j] = filled[i][j]; + if (filled[i][j]) { + if (i == 8 && j == 8) return true; + else return solve(i + (j == 8), (j + 1) % 9); } - } - return false; + int poss = check(i, j); + for (int k = 1; k <= 9; ++k) { + if ((poss & (1 << k)) == 0) { + mat[i][j] = k; + if (i == 8 && j == 8) return true; + if (solve(i + (j == 8), (j + 1) % 9)) return true; + mat[i][j] = filled[i][j]; + } + } + + return false; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - mat.resize(9, vector<int>(9)); - - int n; cin >> n; - for (int cas = 0; cas < n; ++cas) { - for (auto &i : mat) - for (auto &j : i) - cin >> j; - - filled = mat; - - if (solve(0, 0)) - for (auto &i : mat) { - for (auto j : i) cout << j << " "; - cout << ende; - } - else - cout << "No solution" << ende; - } + ios::sync_with_stdio(0); + cin.tie(0); + + mat.resize(9, vector<int>(9)); + + int n; cin >> n; + for (int cas = 0; cas < n; ++cas) { + for (auto &i : mat) + for (auto &j : i) + cin >> j; + + filled = mat; + + if (solve(0, 0)) + for (auto &i : mat) { + for (auto j : i) cout << j << " "; + cout << ende; + } + else + cout << "No solution" << ende; + } - return 0; + return 0; } diff --git a/contests/Cadernaveis/ENGARRAF.cpp b/contests/Cadernaveis/ENGARRAF.cpp index ad23fe03749a52f7cad2fc6f49d31b3b6d289a6e..125b73e14abff795b07019f44f2593d6a90c4896 100644 --- a/contests/Cadernaveis/ENGARRAF.cpp +++ b/contests/Cadernaveis/ENGARRAF.cpp @@ -26,65 +26,65 @@ typedef pair<int,int> ii; vector<ii> graph[MAX]; struct Dijkstra { - int N; - vector<int> dist, vis; + int N; + vector<int> dist, vis; - Dijkstra(int N) : - N(N), dist(N), vis(N) - {} + Dijkstra(int N) : + N(N), dist(N), vis(N) + {} - void init() { - fill(all(dist), inf); - fill(all(vis), 0); - } + void init() { + fill(all(dist), inf); + fill(all(vis), 0); + } - int run(int s, int d) { - set<ii> pq; + int run(int s, int d) { + set<ii> pq; - dist[s] = 0; - pq.insert(ii(0, s)); + dist[s] = 0; + pq.insert(ii(0, s)); - while (pq.size() != 0) { - int u = pq.begin()->se; - pq.erase(pq.begin()); + while (pq.size() != 0) { + int u = pq.begin()->se; + pq.erase(pq.begin()); - if (vis[u]) continue; - vis[u] = 1; + if (vis[u]) continue; + vis[u] = 1; - for (auto i : graph[u]) { - int v = i.fi; - int wt = i.se; + for (auto i : graph[u]) { + int v = i.fi; + int wt = i.se; - if (!vis[v] && dist[v] > dist[u] + wt) { - dist[v] = dist[u] + wt; - pq.insert(ii(dist[v], v)); + if (!vis[v] && dist[v] > dist[u] + wt) { + dist[v] = dist[u] + wt; + pq.insert(ii(dist[v], v)); + } + } } - } - } - return dist[d]; - } + return dist[d]; + } } dijkstra(MAX); int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, m; - while (cin >> n >> m && (n || m)) { - dijkstra.init(); - for (int i = 0; i <= n; ++i) - graph[i].clear(); - - for (int i = 0; i < m; ++i) { - int o, d, t; cin >> o >> d >> t; - graph[o].pb(ii(d, t)); - } + ios::sync_with_stdio(0); + cin.tie(0); + + int n, m; + while (cin >> n >> m && (n || m)) { + dijkstra.init(); + for (int i = 0; i <= n; ++i) + graph[i].clear(); + + for (int i = 0; i < m; ++i) { + int o, d, t; cin >> o >> d >> t; + graph[o].pb(ii(d, t)); + } - int s, t; cin >> s >> t; - int ans = dijkstra.run(s, t); - cout << ((ans == inf) ? -1 : ans) << ende; - } + int s, t; cin >> s >> t; + int ans = dijkstra.run(s, t); + cout << ((ans == inf) ? -1 : ans) << ende; + } - return 0; + return 0; } diff --git a/contests/Cadernaveis/GINCAN11.cpp b/contests/Cadernaveis/GINCAN11.cpp index 9c0a271e0626ee4113b356e07da1fafbbd79ba27..906310ba0aa0ac5c71183c84227c283ce691d05f 100644 --- a/contests/Cadernaveis/GINCAN11.cpp +++ b/contests/Cadernaveis/GINCAN11.cpp @@ -26,33 +26,33 @@ int cont[1010]; vector<int> graph[1010]; void dfs(int x) { - cont[x] = 1; - for (auto i : graph[x]) - if (!cont[i]) - dfs(i); + cont[x] = 1; + for (auto i : graph[x]) + if (!cont[i]) + dfs(i); } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, m, a, b; - cin >> n >> m; - for (int i = 0; i < m; ++i) { - cin >> a >> b; - a--, b--; - graph[a].pb(b); - graph[b].pb(a); - } - - int ans = 0; - for (int i = 0; i < n; ++i) { - if (!cont[i]) { - dfs(i); - ans++; + ios::sync_with_stdio(0); + cin.tie(0); + + int n, m, a, b; + cin >> n >> m; + for (int i = 0; i < m; ++i) { + cin >> a >> b; + a--, b--; + graph[a].pb(b); + graph[b].pb(a); } - } - cout << ans << '\n'; - return 0; + int ans = 0; + for (int i = 0; i < n; ++i) { + if (!cont[i]) { + dfs(i); + ans++; + } + } + + cout << ans << '\n'; + return 0; } diff --git a/contests/Cadernaveis/JANELA13.cpp b/contests/Cadernaveis/JANELA13.cpp index 509abfb0aae66369d22709a86e08f7bcb3285391..d849b018497f011e1d02d8f62f93cf19f1430b7a 100644 --- a/contests/Cadernaveis/JANELA13.cpp +++ b/contests/Cadernaveis/JANELA13.cpp @@ -22,37 +22,37 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n; n = 3; - vector<ii> v; - v.pb(ii(0, -1)); - v.pb(ii(600, 2)); - for (int i = 0; i < n; ++i) { - int x; cin >> x; - v.pb(ii(x, 0)); - v.pb(ii(x+200, 1)); - } - - int curr = 0, ans = 0; - bool count = false; - sort(all(v)); - for (int i = 0; i < v.size(); ++i) { - if (v[i].se == 0) - curr++; - else if (v[i].se == 1) - curr--; - - if (count) { - ans += v[i].fi - v[i-1].fi; - count = false; + ios::sync_with_stdio(0); + cin.tie(0); + + int n; n = 3; + vector<ii> v; + v.pb(ii(0, -1)); + v.pb(ii(600, 2)); + for (int i = 0; i < n; ++i) { + int x; cin >> x; + v.pb(ii(x, 0)); + v.pb(ii(x+200, 1)); } - if (curr == 0) - count = true; - } + int curr = 0, ans = 0; + bool count = false; + sort(all(v)); + for (int i = 0; i < v.size(); ++i) { + if (v[i].se == 0) + curr++; + else if (v[i].se == 1) + curr--; + + if (count) { + ans += v[i].fi - v[i-1].fi; + count = false; + } + + if (curr == 0) + count = true; + } - cout << ans * 100 << ende; - return 0; + cout << ans * 100 << ende; + return 0; } diff --git a/contests/Cadernaveis/KOCH.cpp b/contests/Cadernaveis/KOCH.cpp index 91ff450f6a93d44855d78edf7c9131241223dfae..b55f540b5d527c898c79ba48393fa343e56f0bd9 100644 --- a/contests/Cadernaveis/KOCH.cpp +++ b/contests/Cadernaveis/KOCH.cpp @@ -1,414 +1,414 @@ /// Crescimento das Populacoes de bacilos #include <bits/stdc++.h> - + #define EPS 1e-6 #define MOD 1000000007 #define inf 0x3f3f3f3f #define llinf 0x3f3f3f3f3f3f3f3f - + #define fi first #define se second #define pb push_back #define ende '\n' - + #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() #define mset(x, y) memset(&x, (y), sizeof(x)) - + using namespace std; - + using ll = long long; using ii = pair<int,int>; - + const int base = 1000000000; const int base_d = 9; - + struct BigInt { - int sign; - vector<int> num; - - BigInt() : sign(1) {} - BigInt(ll x) { *this = x; } - BigInt(const string &s) { read(s); } - - void operator=(const BigInt &x) { - sign = x.sign; - num = x.num; - } - - void operator=(ll x) { - sign = 1; - if (x < 0) sign = -1, x = -x; - for (; x > 0; x /= base) - pb(x % base); - } - - BigInt operator+(const BigInt &x) const { - if (sign != x.sign) return *this - (-x); - - - int carry = 0; - BigInt res = x; - - for (int i = 0; i < max(size(), x.size()) || carry; ++i) { - if (i == (int) res.size()) - res.push_back(0); - - res[i] += carry + (i < size() ? num[i] : 0); - carry = res[i] >= base; - if (carry) res[i] -= base; - } - - return res; - } - - BigInt operator-(const BigInt &x) const { - if (sign != x.sign) return *this + (-x); - if (abs() < x.abs()) return -(x - *this); - - int carry = 0; - BigInt res = *this; - - for (int i = 0; i < x.size() || carry; ++i) { - res[i] -= carry + (i < x.size() ? x[i] : 0); - carry = res[i] < 0; - if (carry) res[i] += base; - } - - res.trim(); - return res; - } - - void operator*=(int x) { - if (x < 0) sign = -sign, x = -x; - - int carry = 0; - for (int i = 0; i < size() || carry; ++i) { - if (i == size()) pb(0); - ll cur = num[i] * (ll) x + carry; - - carry = (int) (cur / base); - num[i] = (int) (cur % base); - } - - trim(); - } - - BigInt operator*(int x) const { - BigInt res = *this; - res *= x; - return res; - } - - friend pair<BigInt, BigInt> divmod(const BigInt &a1, - const BigInt &b1) - { - int norm = base / (b1.back() + 1); - BigInt a = a1.abs() * norm; - BigInt b = b1.abs() * norm; - BigInt q, r; - q.resize(a.size()); - - for (int i = a.size() - 1; i >= 0; i--) { - r *= base; - r += a[i]; - - int s1 = r.size() <= b.size() ? 0 : r[b.size()]; - int s2 = r.size() <= b.size() - 1 ? 0 : r[b.size() - 1]; - int d = ((ll) base * s1 + s2) / b.back(); - - r -= b * d; - while (r < 0) r += b, --d; - q[i] = d; - } - - q.sign = a1.sign * b1.sign; - r.sign = a1.sign; - q.trim(); r.trim(); - - return make_pair(q, r / norm); - } - - BigInt operator/(const BigInt &x) const { - return divmod(*this, x).fi; - } - - BigInt operator%(const BigInt &x) const { - return divmod(*this, x).se; - } - - void operator/=(int x) { - if (x < 0) sign = -sign, x = -x; - - for (int i = size() - 1, rem = 0; i >= 0; --i) { - ll cur = num[i] + rem * (ll) base; - num[i] = (int) (cur / x); - rem = (int) (cur % x); - } - - trim(); - } - - BigInt operator/(int x) const { - BigInt res = *this; - res /= x; - return res; - } - - int operator%(int x) const { - if (x < 0) x = -x; - - int m = 0; - for (int i = size() - 1; i >= 0; --i) - m = (num[i] + m * (ll) base) % x; - - return m * sign; - } - - void operator+=(const BigInt &x) { - *this = *this + x; - } - void operator-=(const BigInt &x) { - *this = *this - x; - } - void operator*=(const BigInt &x) { - *this = *this * x; - } - void operator/=(const BigInt &x) { - *this = *this / x; - } - - bool operator<(const BigInt &x) const { - if (sign != x.sign) - return sign < x.sign; - - if (size() != x.size()) - return size() * sign < x.size() * x.sign; - - for (int i = size() - 1; i >= 0; i--) - if (num[i] != x[i]) - return num[i] * sign < x[i] * sign; - - return false; - } - - bool operator>(const BigInt &x) const { - return x < *this; - } - bool operator<=(const BigInt &x) const { - return !(x < *this); - } - bool operator>=(const BigInt &x) const { - return !(*this < x); - } - bool operator==(const BigInt &x) const { - return !(*this < x) && !(x < *this); - } - bool operator!=(const BigInt &x) const { - return *this < x || x < *this; - } - - void trim() { - while (!empty() && !back()) pop_back(); - if (empty()) sign = 1; - } - - bool is_zero() const { - return empty() || (size() == 1 && !num[0]); - } - - BigInt operator-() const { - BigInt res = *this; - res.sign = -sign; - return res; - } - - BigInt abs() const { - BigInt res = *this; - res.sign *= res.sign; - return res; - } - - ll to_long() const { - ll res = 0; - for (int i = size() - 1; i >= 0; i--) - res = res * base + num[i]; - return res * sign; - } - - friend BigInt gcd(const BigInt &a, const BigInt &b) { - return b.is_zero() ? a : gcd(b, a % b); - } - - friend BigInt lcm(const BigInt &a, const BigInt &b) { - return a / gcd(a, b) * b; - } - - void read(const string &s) { - sign = 1; - num.clear(); - - int pos = 0; - while (pos < s.size() && - (s[pos] == '-' || s[pos] == '+')) { - if (s[pos] == '-') - sign = -sign; - ++pos; - } - - for (int i = s.size() - 1; i >= pos; i -= base_d) { - int x = 0; - for (int j = max(pos, i - base_d + 1); j <= i; j++) - x = x * 10 + s[j] - '0'; - num.push_back(x); - } - - trim(); - } - - friend istream& operator>>(istream &stream, BigInt &v) { - string s; stream >> s; - v.read(s); - return stream; - } - - friend ostream& operator<<(ostream &stream, const BigInt &x) { - if (x.sign == -1) - stream << '-'; - - stream << (x.empty() ? 0 : x.back()); - for (int i = x.size() - 2; i >= 0; --i) - stream << setw(base_d) << setfill('0') << x.num[i]; - - return stream; - } - - static vector<int> convert_base(const vector<int> &a, - int oldd, int newd) - { - vector<ll> p(max(oldd, newd) + 1); - p[0] = 1; - for (int i = 1; i < p.size(); i++) - p[i] = p[i - 1] * 10; - - ll cur = 0; - int curd = 0; - vector<int> res; - - for (int i = 0; i < a.size(); i++) { - cur += a[i] * p[curd]; - curd += oldd; - - while (curd >= newd) { - res.pb(int(cur % p[newd])); - cur /= p[newd]; - curd -= newd; - } - } - - res.pb((int) cur); - while (!res.empty() && !res.back()) - res.pop_back(); - return res; - } - - static vector<ll> karatsuba(const vector<ll> &a, - const vector<ll> &b) - { - int n = a.size(); - vector<ll> res(n + n); - - if (n <= 32) { - for (int i = 0; i < n; i++) - for (int j = 0; j < n; j++) - res[i + j] += a[i] * b[j]; - return res; - } - - int k = n >> 1; - vector<ll> a1(a.begin(), a.begin() + k); - vector<ll> a2(a.begin() + k, a.end()); - vector<ll> b1(b.begin(), b.begin() + k); - vector<ll> b2(b.begin() + k, b.end()); - - vector<ll> a1b1 = karatsuba(a1, b1); - vector<ll> a2b2 = karatsuba(a2, b2); - - for (int i = 0; i < k; i++) - a2[i] += a1[i]; - for (int i = 0; i < k; i++) - b2[i] += b1[i]; - - vector<ll> r = karatsuba(a2, b2); - for (int i = 0; i < a1b1.size(); i++) r[i] -= a1b1[i]; - for (int i = 0; i < a2b2.size(); i++) r[i] -= a2b2[i]; - - for (int i = 0; i < r.size(); i++) res[i + k] += r[i]; - for (int i = 0; i < a1b1.size(); i++) res[i] += a1b1[i]; - for (int i = 0; i < a2b2.size(); i++) res[i + n] += a2b2[i]; - - return res; - } - - BigInt operator*(const BigInt &x) const { - vector<int> a6 = convert_base(this->num, base_d, 6); - vector<int> b6 = convert_base(x.num, base_d, 6); - - vector<ll> a(all(a6)); - vector<ll> b(all(b6)); - - while (a.size() < b.size()) a.pb(0); - while (b.size() < a.size()) b.pb(0); - while (a.size() & (a.size() - 1)) - a.pb(0), b.pb(0); - - vector<ll> c = karatsuba(a, b); - - BigInt res; - int carry = 0; - res.sign = sign * x.sign; - - for (int i = 0; i < c.size(); i++) { - ll cur = c[i] + carry; - res.pb((int) (cur % 1000000)); - carry = (int) (cur / 1000000); - } - - res.num = convert_base(res.num, 6, base_d); - res.trim(); - return res; - } - - // Handles vector operations. - int back() const { return num.back(); } - bool empty() const { return num.empty(); } - size_t size() const { return num.size(); } - - void pop_back() { num.pop_back(); } - void resize(int x) { num.resize(x); } - void push_back(int x) { num.push_back(x); } - - int &operator[](int i) { return num[i]; } - int operator[](int i) const { return num[i]; } + int sign; + vector<int> num; + + BigInt() : sign(1) {} + BigInt(ll x) { *this = x; } + BigInt(const string &s) { read(s); } + + void operator=(const BigInt &x) { + sign = x.sign; + num = x.num; + } + + void operator=(ll x) { + sign = 1; + if (x < 0) sign = -1, x = -x; + for (; x > 0; x /= base) + pb(x % base); + } + + BigInt operator+(const BigInt &x) const { + if (sign != x.sign) return *this - (-x); + + + int carry = 0; + BigInt res = x; + + for (int i = 0; i < max(size(), x.size()) || carry; ++i) { + if (i == (int) res.size()) + res.push_back(0); + + res[i] += carry + (i < size() ? num[i] : 0); + carry = res[i] >= base; + if (carry) res[i] -= base; + } + + return res; + } + + BigInt operator-(const BigInt &x) const { + if (sign != x.sign) return *this + (-x); + if (abs() < x.abs()) return -(x - *this); + + int carry = 0; + BigInt res = *this; + + for (int i = 0; i < x.size() || carry; ++i) { + res[i] -= carry + (i < x.size() ? x[i] : 0); + carry = res[i] < 0; + if (carry) res[i] += base; + } + + res.trim(); + return res; + } + + void operator*=(int x) { + if (x < 0) sign = -sign, x = -x; + + int carry = 0; + for (int i = 0; i < size() || carry; ++i) { + if (i == size()) pb(0); + ll cur = num[i] * (ll) x + carry; + + carry = (int) (cur / base); + num[i] = (int) (cur % base); + } + + trim(); + } + + BigInt operator*(int x) const { + BigInt res = *this; + res *= x; + return res; + } + + friend pair<BigInt, BigInt> divmod(const BigInt &a1, + const BigInt &b1) + { + int norm = base / (b1.back() + 1); + BigInt a = a1.abs() * norm; + BigInt b = b1.abs() * norm; + BigInt q, r; + q.resize(a.size()); + + for (int i = a.size() - 1; i >= 0; i--) { + r *= base; + r += a[i]; + + int s1 = r.size() <= b.size() ? 0 : r[b.size()]; + int s2 = r.size() <= b.size() - 1 ? 0 : r[b.size() - 1]; + int d = ((ll) base * s1 + s2) / b.back(); + + r -= b * d; + while (r < 0) r += b, --d; + q[i] = d; + } + + q.sign = a1.sign * b1.sign; + r.sign = a1.sign; + q.trim(); r.trim(); + + return make_pair(q, r / norm); + } + + BigInt operator/(const BigInt &x) const { + return divmod(*this, x).fi; + } + + BigInt operator%(const BigInt &x) const { + return divmod(*this, x).se; + } + + void operator/=(int x) { + if (x < 0) sign = -sign, x = -x; + + for (int i = size() - 1, rem = 0; i >= 0; --i) { + ll cur = num[i] + rem * (ll) base; + num[i] = (int) (cur / x); + rem = (int) (cur % x); + } + + trim(); + } + + BigInt operator/(int x) const { + BigInt res = *this; + res /= x; + return res; + } + + int operator%(int x) const { + if (x < 0) x = -x; + + int m = 0; + for (int i = size() - 1; i >= 0; --i) + m = (num[i] + m * (ll) base) % x; + + return m * sign; + } + + void operator+=(const BigInt &x) { + *this = *this + x; + } + void operator-=(const BigInt &x) { + *this = *this - x; + } + void operator*=(const BigInt &x) { + *this = *this * x; + } + void operator/=(const BigInt &x) { + *this = *this / x; + } + + bool operator<(const BigInt &x) const { + if (sign != x.sign) + return sign < x.sign; + + if (size() != x.size()) + return size() * sign < x.size() * x.sign; + + for (int i = size() - 1; i >= 0; i--) + if (num[i] != x[i]) + return num[i] * sign < x[i] * sign; + + return false; + } + + bool operator>(const BigInt &x) const { + return x < *this; + } + bool operator<=(const BigInt &x) const { + return !(x < *this); + } + bool operator>=(const BigInt &x) const { + return !(*this < x); + } + bool operator==(const BigInt &x) const { + return !(*this < x) && !(x < *this); + } + bool operator!=(const BigInt &x) const { + return *this < x || x < *this; + } + + void trim() { + while (!empty() && !back()) pop_back(); + if (empty()) sign = 1; + } + + bool is_zero() const { + return empty() || (size() == 1 && !num[0]); + } + + BigInt operator-() const { + BigInt res = *this; + res.sign = -sign; + return res; + } + + BigInt abs() const { + BigInt res = *this; + res.sign *= res.sign; + return res; + } + + ll to_long() const { + ll res = 0; + for (int i = size() - 1; i >= 0; i--) + res = res * base + num[i]; + return res * sign; + } + + friend BigInt gcd(const BigInt &a, const BigInt &b) { + return b.is_zero() ? a : gcd(b, a % b); + } + + friend BigInt lcm(const BigInt &a, const BigInt &b) { + return a / gcd(a, b) * b; + } + + void read(const string &s) { + sign = 1; + num.clear(); + + int pos = 0; + while (pos < s.size() && + (s[pos] == '-' || s[pos] == '+')) { + if (s[pos] == '-') + sign = -sign; + ++pos; + } + + for (int i = s.size() - 1; i >= pos; i -= base_d) { + int x = 0; + for (int j = max(pos, i - base_d + 1); j <= i; j++) + x = x * 10 + s[j] - '0'; + num.push_back(x); + } + + trim(); + } + + friend istream& operator>>(istream &stream, BigInt &v) { + string s; stream >> s; + v.read(s); + return stream; + } + + friend ostream& operator<<(ostream &stream, const BigInt &x) { + if (x.sign == -1) + stream << '-'; + + stream << (x.empty() ? 0 : x.back()); + for (int i = x.size() - 2; i >= 0; --i) + stream << setw(base_d) << setfill('0') << x.num[i]; + + return stream; + } + + static vector<int> convert_base(const vector<int> &a, + int oldd, int newd) + { + vector<ll> p(max(oldd, newd) + 1); + p[0] = 1; + for (int i = 1; i < p.size(); i++) + p[i] = p[i - 1] * 10; + + ll cur = 0; + int curd = 0; + vector<int> res; + + for (int i = 0; i < a.size(); i++) { + cur += a[i] * p[curd]; + curd += oldd; + + while (curd >= newd) { + res.pb(int(cur % p[newd])); + cur /= p[newd]; + curd -= newd; + } + } + + res.pb((int) cur); + while (!res.empty() && !res.back()) + res.pop_back(); + return res; + } + + static vector<ll> karatsuba(const vector<ll> &a, + const vector<ll> &b) + { + int n = a.size(); + vector<ll> res(n + n); + + if (n <= 32) { + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) + res[i + j] += a[i] * b[j]; + return res; + } + + int k = n >> 1; + vector<ll> a1(a.begin(), a.begin() + k); + vector<ll> a2(a.begin() + k, a.end()); + vector<ll> b1(b.begin(), b.begin() + k); + vector<ll> b2(b.begin() + k, b.end()); + + vector<ll> a1b1 = karatsuba(a1, b1); + vector<ll> a2b2 = karatsuba(a2, b2); + + for (int i = 0; i < k; i++) + a2[i] += a1[i]; + for (int i = 0; i < k; i++) + b2[i] += b1[i]; + + vector<ll> r = karatsuba(a2, b2); + for (int i = 0; i < a1b1.size(); i++) r[i] -= a1b1[i]; + for (int i = 0; i < a2b2.size(); i++) r[i] -= a2b2[i]; + + for (int i = 0; i < r.size(); i++) res[i + k] += r[i]; + for (int i = 0; i < a1b1.size(); i++) res[i] += a1b1[i]; + for (int i = 0; i < a2b2.size(); i++) res[i + n] += a2b2[i]; + + return res; + } + + BigInt operator*(const BigInt &x) const { + vector<int> a6 = convert_base(this->num, base_d, 6); + vector<int> b6 = convert_base(x.num, base_d, 6); + + vector<ll> a(all(a6)); + vector<ll> b(all(b6)); + + while (a.size() < b.size()) a.pb(0); + while (b.size() < a.size()) b.pb(0); + while (a.size() & (a.size() - 1)) + a.pb(0), b.pb(0); + + vector<ll> c = karatsuba(a, b); + + BigInt res; + int carry = 0; + res.sign = sign * x.sign; + + for (int i = 0; i < c.size(); i++) { + ll cur = c[i] + carry; + res.pb((int) (cur % 1000000)); + carry = (int) (cur / 1000000); + } + + res.num = convert_base(res.num, 6, base_d); + res.trim(); + return res; + } + + // Handles vector operations. + int back() const { return num.back(); } + bool empty() const { return num.empty(); } + size_t size() const { return num.size(); } + + void pop_back() { num.pop_back(); } + void resize(int x) { num.resize(x); } + void push_back(int x) { num.push_back(x); } + + int &operator[](int i) { return num[i]; } + int operator[](int i) const { return num[i]; } }; - + int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - vector<int> fib(1501); - fib[0] = 0; - fib[1] = 1; - for (int i = 2; i <= 1500; ++i) - fib[i] = (fib[i-1] + fib[i-2]) % 1000; - - int t; cin >> t; - for (int cas = 1; cas <= t; ++cas) { - BigInt x; cin >> x; - x = x % BigInt(1500); - cout << setw(3) << setfill('0') << fib[x.to_long()]<< ende; - } - - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + vector<int> fib(1501); + fib[0] = 0; + fib[1] = 1; + for (int i = 2; i <= 1500; ++i) + fib[i] = (fib[i-1] + fib[i-2]) % 1000; + + int t; cin >> t; + for (int cas = 1; cas <= t; ++cas) { + BigInt x; cin >> x; + x = x % BigInt(1500); + cout << setw(3) << setfill('0') << fib[x.to_long()]<< ende; + } + + return 0; } diff --git a/contests/Cadernaveis/KRAKOVIA.cpp b/contests/Cadernaveis/KRAKOVIA.cpp index fb390d9d53c4fa932dd07eb7f48b9e76b4b761f9..a41a86518dc17dc8b6664f45dd342385dc36f250 100644 --- a/contests/Cadernaveis/KRAKOVIA.cpp +++ b/contests/Cadernaveis/KRAKOVIA.cpp @@ -25,245 +25,245 @@ const int base = 1000000000; const int base_d = 9; struct BigInt { - int sign = 1; - vector<int> num; + int sign = 1; + vector<int> num; + + BigInt() {} + BigInt(ll x) { *this = x; } + BigInt(const string &x) { read(x); } + + void operator=(ll x) { + sign = 1; + if (x < 0) sign = -1, x = -x; + for (; x > 0; x /= base) + num.pb(x % base); + } + + BigInt operator+(const BigInt &x) const { + if (sign != x.sign) return *this - (-x); + + BigInt ans = x; + int carry = 0; + for (int i = 0; i < max(size(), x.size()) || carry; ++i) { + if (i == ans.size()) ans.push_back(0); - BigInt() {} - BigInt(ll x) { *this = x; } - BigInt(const string &x) { read(x); } + if (i < size()) ans[i] += carry + num[i]; + else ans[i] += carry; - void operator=(ll x) { - sign = 1; - if (x < 0) sign = -1, x = -x; - for (; x > 0; x /= base) - num.pb(x % base); - } + carry = ans[i] >= base; + if (carry) ans[i] -= base; + } - BigInt operator+(const BigInt &x) const { - if (sign != x.sign) return *this - (-x); + return ans; + } + + BigInt operator-(const BigInt& x) const { + if (sign != x.sign) + return *this + (-x); + if (abs() < x.abs()) + return -(x - *this); - BigInt ans = x; - int carry = 0; - for (int i = 0; i < max(size(), x.size()) || carry; ++i) { - if (i == ans.size()) ans.push_back(0); + BigInt ans = *this; + int carry = 0; + for (int i = 0; i < x.size() || carry; ++i) { + if (i < x.size()) ans[i] -= carry + x[i]; + else ans[i] -= carry; - if (i < size()) ans[i] += carry + num[i]; - else ans[i] += carry; + carry = ans[i] < 0; + if (carry) ans[i] += base; + } - carry = ans[i] >= base; - if (carry) ans[i] -= base; + ans.trim(); + return ans; } - return ans; - } + void operator+=(const BigInt &v) { + *this = *this + v; + } + void operator-=(const BigInt &v) { + *this = *this - v; + } - BigInt operator-(const BigInt& x) const { - if (sign != x.sign) - return *this + (-x); - if (abs() < x.abs()) - return -(x - *this); + void operator*=(int v) { + if (v < 0) sign = -sign, v = -v; + for (int i = 0, carry = 0; i < (int) size() || carry; ++i) { + if (i == (int) size()) + num.push_back(0); - BigInt ans = *this; - int carry = 0; - for (int i = 0; i < x.size() || carry; ++i) { - if (i < x.size()) ans[i] -= carry + x[i]; - else ans[i] -= carry; + ll cur = num[i] * (ll) v + carry; + carry = (int) (cur / base); + num[i] = (int) (cur % base); + } - carry = ans[i] < 0; - if (carry) ans[i] += base; + trim(); } - ans.trim(); - return ans; - } - - void operator+=(const BigInt &v) { - *this = *this + v; - } - void operator-=(const BigInt &v) { - *this = *this - v; - } - - void operator*=(int v) { - if (v < 0) sign = -sign, v = -v; - for (int i = 0, carry = 0; i < (int) size() || carry; ++i) { - if (i == (int) size()) - num.push_back(0); - - ll cur = num[i] * (ll) v + carry; - carry = (int) (cur / base); - num[i] = (int) (cur % base); + BigInt operator*(int v) const { + BigInt res = *this; + res *= v; + return res; } - trim(); - } - - BigInt operator*(int v) const { - BigInt res = *this; - res *= v; - return res; - } - - // Returns pair = (x / y, x % y). - friend pair<BigInt,BigInt> divmod(const BigInt &x, - const BigInt &y) { - int norm = base / (y.back() + 1); - - BigInt a = x.abs() * norm; - BigInt b = y.abs() * norm; - BigInt q, r; - q.num.resize(a.size()); - - for (int i = a.size() - 1; i >= 0; i--) { - r *= base; - r += a[i]; - int s1 = r.size() <= b.size() ? 0 : r.num[b.size()]; - int s2 = r.size() <= b.size() - 1 ? 0 : r.num[b.size() - 1]; - - int d = ((ll) base * s1 + s2) / b.back(); - r -= b * d; - while (r < 0) r += b, --d; - q.num[i] = d; + // Returns pair = (x / y, x % y). + friend pair<BigInt,BigInt> divmod(const BigInt &x, + const BigInt &y) { + int norm = base / (y.back() + 1); + + BigInt a = x.abs() * norm; + BigInt b = y.abs() * norm; + BigInt q, r; + q.num.resize(a.size()); + + for (int i = a.size() - 1; i >= 0; i--) { + r *= base; + r += a[i]; + int s1 = r.size() <= b.size() ? 0 : r.num[b.size()]; + int s2 = r.size() <= b.size() - 1 ? 0 : r.num[b.size() - 1]; + + int d = ((ll) base * s1 + s2) / b.back(); + r -= b * d; + while (r < 0) r += b, --d; + q.num[i] = d; + } + + q.sign = x.sign * y.sign; + r.sign = x.sign; + q.trim(); r.trim(); + return make_pair(q, r / norm); } - q.sign = x.sign * y.sign; - r.sign = x.sign; - q.trim(); r.trim(); - return make_pair(q, r / norm); - } + BigInt operator/(const BigInt &x) const { + return divmod(*this, x).fi; + } - BigInt operator/(const BigInt &x) const { - return divmod(*this, x).fi; - } + void operator/=(int v) { + if (v < 0) sign = -sign, v = -v; - void operator/=(int v) { - if (v < 0) sign = -sign, v = -v; + for (int i = (int) size() - 1, rem = 0; i >= 0; --i) { + ll cur = num[i] + rem * (ll) base; + num[i] = (int) (cur / v); + rem = (int) (cur % v); + } - for (int i = (int) size() - 1, rem = 0; i >= 0; --i) { - ll cur = num[i] + rem * (ll) base; - num[i] = (int) (cur / v); - rem = (int) (cur % v); + trim(); } - trim(); - } - - BigInt operator/(int x) const { - BigInt res = *this; - res /= x; - return res; - } - - // Removes leading zeros. - void trim() { - while (!num.empty() && num.back() == 0) - num.pop_back(); - - if (num.empty()) - sign = 1; - } - - bool operator<(const BigInt &x) const { - if (sign != x.sign) - return sign < x.sign; - - if (size() != x.size()) - return (size() * sign) < (x.size() * x.sign); - - for (int i = size() - 1; i >= 0; i--) - if (num[i] != x[i]) - return (num[i] * sign) < (x[i] * x.sign); - - return false; - } - - bool operator==(const BigInt &x) const { return !(*this < x) && !(x < *this); } - bool operator>(const BigInt &x) const { return (x < *this); } - bool operator<=(const BigInt &x) const { return !(x < *this); } - bool operator>=(const BigInt &x) const { return !(*this < x); } - bool operator!=(const BigInt &x) const { return !(*this == x); } - - // Handles -x (change of sign). - BigInt operator-() const { - BigInt ans = *this; - ans.sign = -sign; - return ans; - } - - // Returs absolute value. - BigInt abs() const { - BigInt ans = *this; - ans.sign *= ans.sign; - return ans; - } - - // Transforms string into BigInt. - void read(const string &s) { - sign = 1; - num.clear(); - - int pos = 0; - while (pos < (int) s.size() && - (s[pos] == '-' || s[pos] == '+')) - { - if (s[pos] == '-') - sign = -sign; - ++pos; + BigInt operator/(int x) const { + BigInt res = *this; + res /= x; + return res; } - for (int i = s.size() - 1; i >= pos; i -= base_d) { - int x = 0; - for (int j = max(pos, i - base_d + 1); j <= i; j++) - x = x * 10 + s[j] - '0'; - num.push_back(x); + // Removes leading zeros. + void trim() { + while (!num.empty() && num.back() == 0) + num.pop_back(); + + if (num.empty()) + sign = 1; } - trim(); - } + bool operator<(const BigInt &x) const { + if (sign != x.sign) + return sign < x.sign; - friend istream& operator>>(istream &stream, BigInt &v) { - string s; stream >> s; - v.read(s); - return stream; - } + if (size() != x.size()) + return (size() * sign) < (x.size() * x.sign); - friend ostream& operator<<(ostream &stream, - const BigInt &x) { - if (x.sign == -1) - stream << '-'; + for (int i = size() - 1; i >= 0; i--) + if (num[i] != x[i]) + return (num[i] * sign) < (x[i] * x.sign); - stream << (x.empty() ? 0 : x.back()); - for (int i = x.size() - 2; i >= 0; --i) - stream << setw(base_d) << setfill('0') << x.num[i]; + return false; + } - return stream; - } + bool operator==(const BigInt &x) const { return !(*this < x) && !(x < *this); } + bool operator>(const BigInt &x) const { return (x < *this); } + bool operator<=(const BigInt &x) const { return !(x < *this); } + bool operator>=(const BigInt &x) const { return !(*this < x); } + bool operator!=(const BigInt &x) const { return !(*this == x); } + + // Handles -x (change of sign). + BigInt operator-() const { + BigInt ans = *this; + ans.sign = -sign; + return ans; + } - // Handles vector operations. - int back() const { return num.back(); } - bool empty() const { return num.empty(); } - size_t size() const { return num.size(); } - void push_back(int x) { num.push_back(x); } + // Returs absolute value. + BigInt abs() const { + BigInt ans = *this; + ans.sign *= ans.sign; + return ans; + } - int &operator[](int i) { return num[i]; } - int operator[](int i) const { return num[i]; } + // Transforms string into BigInt. + void read(const string &s) { + sign = 1; + num.clear(); + + int pos = 0; + while (pos < (int) s.size() && + (s[pos] == '-' || s[pos] == '+')) + { + if (s[pos] == '-') + sign = -sign; + ++pos; + } + + for (int i = s.size() - 1; i >= pos; i -= base_d) { + int x = 0; + for (int j = max(pos, i - base_d + 1); j <= i; j++) + x = x * 10 + s[j] - '0'; + num.push_back(x); + } + + trim(); + } + + friend istream& operator>>(istream &stream, BigInt &v) { + string s; stream >> s; + v.read(s); + return stream; + } + + friend ostream& operator<<(ostream &stream, + const BigInt &x) { + if (x.sign == -1) + stream << '-'; + + stream << (x.empty() ? 0 : x.back()); + for (int i = x.size() - 2; i >= 0; --i) + stream << setw(base_d) << setfill('0') << x.num[i]; + + return stream; + } + + // Handles vector operations. + int back() const { return num.back(); } + bool empty() const { return num.empty(); } + size_t size() const { return num.size(); } + void push_back(int x) { num.push_back(x); } + + int &operator[](int i) { return num[i]; } + int operator[](int i) const { return num[i]; } }; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, f, cas = 1; - while (cin >> n >> f && (n || f)) { - vector<BigInt> v(n); - for (int i = 0; i < n; ++i) - cin >> v[i]; - - BigInt sum = accumulate(all(v), BigInt("0")); - cout << "Bill #" << cas << " costs " << sum << ": each friend should pay " << sum / f << ende; - cout << ende; - cas++; - } - - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int n, f, cas = 1; + while (cin >> n >> f && (n || f)) { + vector<BigInt> v(n); + for (int i = 0; i < n; ++i) + cin >> v[i]; + + BigInt sum = accumulate(all(v), BigInt("0")); + cout << "Bill #" << cas << " costs " << sum << ": each friend should pay " << sum / f << ende; + cout << ende; + cas++; + } + + return 0; } diff --git a/contests/Cadernaveis/LA3635.cpp b/contests/Cadernaveis/LA3635.cpp index 212d07ee96ce254503465f28bfeb4b08fbd41154..f9bf000c5cc6677a4154678f0d86fcf46f67125e 100644 --- a/contests/Cadernaveis/LA3635.cpp +++ b/contests/Cadernaveis/LA3635.cpp @@ -23,33 +23,33 @@ typedef long long ll; typedef pair<int,int> ii; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - cout << setprecision(9) << fixed; - - int t; cin >> t; - while (t--) { - int n, f; cin >> n >> f; - vector<double> v(n); - for (auto &i : v) - cin >> i; - - double l = 0.0, r = (double) llinf; - for (int i = 0; i < 300; ++i) { - double m = (l + r) / 2.0; - int p = 0; - - for (int j = 0; j < n; ++j) - p += (int) floor((v[j] * v[j] * M_PI) / m); - - if (p >= f + 1) - l = m; - else - r = m; + ios::sync_with_stdio(0); + cin.tie(0); + cout << setprecision(9) << fixed; + + int t; cin >> t; + while (t--) { + int n, f; cin >> n >> f; + vector<double> v(n); + for (auto &i : v) + cin >> i; + + double l = 0.0, r = (double) llinf; + for (int i = 0; i < 300; ++i) { + double m = (l + r) / 2.0; + int p = 0; + + for (int j = 0; j < n; ++j) + p += (int) floor((v[j] * v[j] * M_PI) / m); + + if (p >= f + 1) + l = m; + else + r = m; + } + + cout << l << ende; } - cout << l << ende; - } - - return 0; + return 0; } diff --git a/contests/Cadernaveis/LA4509.cpp b/contests/Cadernaveis/LA4509.cpp index cd2de3fbe06e99afc617c392f82e4f04cc544adb..d4ba0c7f393dc318b87bb2d1dfcc9bdf45e619ce 100644 --- a/contests/Cadernaveis/LA4509.cpp +++ b/contests/Cadernaveis/LA4509.cpp @@ -28,85 +28,85 @@ int dy[] = {0, 0, 1, -1}; int mat[MAX][MAX]; struct BellmanFord { - struct Edge { int u, v, w; }; + struct Edge { int u, v, w; }; - int N; - vector<int> dist; - vector<Edge> graph; + int N; + vector<int> dist; + vector<Edge> graph; - BellmanFord(int N) : - N(N), dist(N) - { init(); } + BellmanFord(int N) : + N(N), dist(N) + { init(); } - void init() { - fill(all(dist), inf); - } + void init() { + fill(all(dist), inf); + } - void add_edge(int u, int v, int w) { - graph.pb({ u, v, w }); - } + void add_edge(int u, int v, int w) { + graph.pb({ u, v, w }); + } - int run(int s, int d) { - dist[s] = 0; + int run(int s, int d) { + dist[s] = 0; - for (int i = 0; i < N; ++i) - for (auto e : graph) - if (dist[e.u] != inf && - dist[e.u] + e.w < dist[e.v]) - dist[e.v] = dist[e.u] + e.w; + for (int i = 0; i < N; ++i) + for (auto e : graph) + if (dist[e.u] != inf && + dist[e.u] + e.w < dist[e.v]) + dist[e.v] = dist[e.u] + e.w; - for (auto e : graph) - if (dist[e.u] != inf && - dist[e.u] + e.w < dist[e.v]) - return -inf; + for (auto e : graph) + if (dist[e.u] != inf && + dist[e.u] + e.w < dist[e.v]) + return -inf; - return dist[d]; - } + return dist[d]; + } }; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int r, c; - while (cin >> c >> r && (c || r)) { - mset(mat, 0); - BellmanFord bell(r*c); - - int g; cin >> g; - for (int i = 0; i < g; ++i) { - int x, y; cin >> x >> y; - mat[y][x] = 1; - } - - int e; cin >> e; - for (int i = 0; i < e; ++i) { - int x1, y1; cin >> x1 >> y1; - int x2, y2; cin >> x2 >> y2; - int t; cin >> t; - - bell.add_edge(y1 * c + x1, y2 * c + x2, t); - mat[y1][x1] = 1; + ios::sync_with_stdio(0); + cin.tie(0); + + int r, c; + while (cin >> c >> r && (c || r)) { + mset(mat, 0); + BellmanFord bell(r*c); + + int g; cin >> g; + for (int i = 0; i < g; ++i) { + int x, y; cin >> x >> y; + mat[y][x] = 1; + } + + int e; cin >> e; + for (int i = 0; i < e; ++i) { + int x1, y1; cin >> x1 >> y1; + int x2, y2; cin >> x2 >> y2; + int t; cin >> t; + + bell.add_edge(y1 * c + x1, y2 * c + x2, t); + mat[y1][x1] = 1; + } + + mat[r-1][c-1] = 1; + for (int i = 0; i < r; ++i) + for (int j = 0; j < c; ++j) + if (!mat[i][j]) + for (int k = 0; k < 4; ++k) { + int di = i + dx[k]; + int dj = j + dy[k]; + + if (di >= 0 && di < r && dj >= 0 && dj < c) + bell.add_edge(i*c + j, di*c + dj, 1); + } + + int ans = bell.run(0, (r-1)*c + (c-1)); + + if (ans == -inf) cout << "Never" << ende; + else if (ans == inf) cout << "Impossible" << ende; + else cout << ans << ende; } - mat[r-1][c-1] = 1; - for (int i = 0; i < r; ++i) - for (int j = 0; j < c; ++j) - if (!mat[i][j]) - for (int k = 0; k < 4; ++k) { - int di = i + dx[k]; - int dj = j + dy[k]; - - if (di >= 0 && di < r && dj >= 0 && dj < c) - bell.add_edge(i*c + j, di*c + dj, 1); - } - - int ans = bell.run(0, (r-1)*c + (c-1)); - - if (ans == -inf) cout << "Never" << ende; - else if (ans == inf) cout << "Impossible" << ende; - else cout << ans << ende; - } - - return 0; + return 0; } diff --git a/contests/Cadernaveis/LA5138.cpp b/contests/Cadernaveis/LA5138.cpp index 349eab9a064dbe7058c3c760873fdb1d5ab70e0a..6a2eb3f3934e76d60a0700d3e2c13ee1fe03131f 100644 --- a/contests/Cadernaveis/LA5138.cpp +++ b/contests/Cadernaveis/LA5138.cpp @@ -23,89 +23,89 @@ using ii = pair<int,int>; template <typename T = double> struct Point { - T x, y; + T x, y; - Point() {} - Point(T x, T y) : x(x), y(y) {} + Point() {} + Point(T x, T y) : x(x), y(y) {} - Point operator+(Point p) { return Point(x+p.x, y+p.y); } - Point operator-(Point p) { return Point(x-p.x, y-p.y); } - Point operator*(T s) { return Point(x*s, y*s); } + Point operator+(Point p) { return Point(x+p.x, y+p.y); } + Point operator-(Point p) { return Point(x-p.x, y-p.y); } + Point operator*(T s) { return Point(x*s, y*s); } - T dot(Point p) { return (x*p.x) + (y*p.y); } - T cross(Point p) { return (x*p.y) - (y*p.x); } + T dot(Point p) { return (x*p.x) + (y*p.y); } + T cross(Point p) { return (x*p.y) - (y*p.x); } }; bool cw(Point<> a, Point<> b, Point<> c) { - return (b - a).cross(c - a) <= 0; + return (b - a).cross(c - a) <= 0; } template <typename T = double> struct Segment { - Point<T> a, b; + Point<T> a, b; - Segment(Point<T> a, Point<T> b) : a(a), b(b) {} + Segment(Point<T> a, Point<T> b) : a(a), b(b) {} - double dist(Point<T> p) { - return (a - b).cross(p - b)/sqrt((b - a).dot(b - a)); - } + double dist(Point<T> p) { + return (a - b).cross(p - b)/sqrt((b - a).dot(b - a)); + } }; vector<Point<>> convex_hull(vector<Point<>> &v) { - int k = 0; - vector<Point<>> ans(v.size() * 2); + int k = 0; + vector<Point<>> ans(v.size() * 2); - sort(all(v), [](const Point<> &a, const Point<> &b) { - return (a.x == b.x) ? (a.y < b.y) : (a.x < b.x); - }); + sort(all(v), [](const Point<> &a, const Point<> &b) { + return (a.x == b.x) ? (a.y < b.y) : (a.x < b.x); + }); - for (int i = 0; i < v.size(); ++i) { - for (; k >= 2 && cw(ans[k-2], ans[k-1], v[i]); --k); - ans[k++] = v[i]; - } + for (int i = 0; i < v.size(); ++i) { + for (; k >= 2 && cw(ans[k-2], ans[k-1], v[i]); --k); + ans[k++] = v[i]; + } - for (int i = v.size() - 2, t = k + 1; i >= 0; --i) { - for (; k >= t && cw(ans[k-2], ans[k-1], v[i]); --k); - ans[k++] = v[i]; - } + for (int i = v.size() - 2, t = k + 1; i >= 0; --i) { + for (; k >= t && cw(ans[k-2], ans[k-1], v[i]); --k); + ans[k++] = v[i]; + } - ans.resize(k); - return ans; + ans.resize(k); + return ans; } double width(vector<Point<>> &v) { - vector<Point<>> h = convex_hull(v); + vector<Point<>> h = convex_hull(v); - int n = h.size() - 1; - double ans = 1e14; + int n = h.size() - 1; + double ans = 1e14; - h[0] = h[n]; - for (int i = 1, j = 1; i <= n; ++i) { - while ((h[i] - h[i-1]).cross(h[j%n+1] - h[i-1]) > - (h[i] - h[i-1]).cross(h[j] - h[i-1])) - j = j % n + 1; + h[0] = h[n]; + for (int i = 1, j = 1; i <= n; ++i) { + while ((h[i] - h[i-1]).cross(h[j%n+1] - h[i-1]) > + (h[i] - h[i-1]).cross(h[j] - h[i-1])) + j = j % n + 1; - Segment<> seg(h[i], h[i-1]); - ans = min(ans, seg.dist(h[j])); - } + Segment<> seg(h[i], h[i-1]); + ans = min(ans, seg.dist(h[j])); + } - return ceil(ans*100)/100; + return ceil(ans*100)/100; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - cout << setprecision(2) << fixed; + ios::sync_with_stdio(0); + cin.tie(0); + cout << setprecision(2) << fixed; - int n, cas = 1; - while (cin >> n && n) { - vector<Point<>> v(n); - for (int i = 0; i < n; ++i) - cin >> v[i].x >> v[i].y; + int n, cas = 1; + while (cin >> n && n) { + vector<Point<>> v(n); + for (int i = 0; i < n; ++i) + cin >> v[i].x >> v[i].y; - cout << "Case " << cas << ": " << width(v) << ende; - cas++; - } + cout << "Case " << cas << ": " << width(v) << ende; + cas++; + } - return 0; + return 0; } diff --git a/contests/Cadernaveis/LA5220.cpp b/contests/Cadernaveis/LA5220.cpp index 0a1d6a34067d1f24475c0577aa6dd81b5e164113..eef3ebc2e0cff9b28e8675b7c4e4f2e622c38533 100644 --- a/contests/Cadernaveis/LA5220.cpp +++ b/contests/Cadernaveis/LA5220.cpp @@ -30,75 +30,75 @@ int graph[MAX][MAX], rg[MAX][MAX]; bool cont[MAX]; bool path(int s, int t) { - queue<int> Q; - Q.push(s); - cont[s] = true; - - while (!Q.empty()) { - int u = Q.front(); Q.pop(); - - if (u == t) - return true; - - for (int i = 0; i < N; ++i) - if (!cont[i] && rg[u][i]) { - cont[i] = true; - par[i] = u; - Q.push(i); - } - } + queue<int> Q; + Q.push(s); + cont[s] = true; + + while (!Q.empty()) { + int u = Q.front(); Q.pop(); + + if (u == t) + return true; + + for (int i = 0; i < N; ++i) + if (!cont[i] && rg[u][i]) { + cont[i] = true; + par[i] = u; + Q.push(i); + } + } - return false; + return false; } int edmonds_karp(int s, int t) { - int ans = 0; - par[s] = -1; + int ans = 0; + par[s] = -1; - mset(cont, 0); - memcpy(rg, graph, sizeof(graph)); + mset(cont, 0); + memcpy(rg, graph, sizeof(graph)); - while (path(s, t)) { - int flow = inf; + while (path(s, t)) { + int flow = inf; - for (int i = t; par[i] != -1; i = par[i]) - flow = min(flow, rg[par[i]][i]); + for (int i = t; par[i] != -1; i = par[i]) + flow = min(flow, rg[par[i]][i]); - for (int i = t; par[i] != -1; i = par[i]) { - rg[par[i]][i] -= flow; - rg[i][par[i]] += flow; - } + for (int i = t; par[i] != -1; i = par[i]) { + rg[par[i]][i] -= flow; + rg[i][par[i]] += flow; + } - ans += flow; - mset(cont, 0); - } + ans += flow; + mset(cont, 0); + } - return ans; + return ans; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, cas = 1; - while (cin >> n && n) { - N = n; - int s, t, c; cin >> s >> t >> c; - - mset(graph, 0); - for (int i = 0; i < c; ++i) { - int o, d, ca; cin >> o >> d >> ca; - o--, d--; - graph[o][d] += ca; - graph[d][o] += ca; + ios::sync_with_stdio(0); + cin.tie(0); + + int n, cas = 1; + while (cin >> n && n) { + N = n; + int s, t, c; cin >> s >> t >> c; + + mset(graph, 0); + for (int i = 0; i < c; ++i) { + int o, d, ca; cin >> o >> d >> ca; + o--, d--; + graph[o][d] += ca; + graph[d][o] += ca; + } + + cout << "Network " << cas++ << ende; + cout << "The bandwidth is " << edmonds_karp(s-1, t-1) << "." << ende; + cout << ende; } - cout << "Network " << cas++ << ende; - cout << "The bandwidth is " << edmonds_karp(s-1, t-1) << "." << ende; - cout << ende; - } - - return 0; + return 0; } diff --git a/contests/Cadernaveis/MANUT.cpp b/contests/Cadernaveis/MANUT.cpp index a4e6b9e280a5a33884b455a7607de3efd410f20f..bf7bccf51efebf0f6eba554c120f143d94764459 100644 --- a/contests/Cadernaveis/MANUT.cpp +++ b/contests/Cadernaveis/MANUT.cpp @@ -30,71 +30,71 @@ int low[MAX]; vector<int> articulations; void dfs(int x) { - int child = 0; - visited[x] = 1; + int child = 0; + visited[x] = 1; - for (auto i : graph[x]) { - if (!visited[i]) { - child++; - parent[i] = x; + for (auto i : graph[x]) { + if (!visited[i]) { + child++; + parent[i] = x; - low[i] = L[i] = L[x] + 1; - dfs(i); + low[i] = L[i] = L[x] + 1; + dfs(i); - low[x] = min(low[x], low[i]); + low[x] = min(low[x], low[i]); - if ((parent[x] == -1 && child > 1) || - (parent[x] != -1 && low[i] >= L[x])) - articulations.pb(x); + if ((parent[x] == -1 && child > 1) || + (parent[x] != -1 && low[i] >= L[x])) + articulations.pb(x); - } else if (parent[x] != i) - low[x] = min(low[x], L[i]); - } + } else if (parent[x] != i) + low[x] = min(low[x], L[i]); + } } void tarjan(int n) { - mset(L, 0); - mset(visited, 0); - mset(parent, -1); - articulations.clear(); + mset(L, 0); + mset(visited, 0); + mset(parent, -1); + articulations.clear(); - dfs(n); + dfs(n); - sort(all(articulations)); - articulations.erase(unique(all(articulations)), articulations.end()); + sort(all(articulations)); + articulations.erase(unique(all(articulations)), articulations.end()); } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, m; - int cas = 1; - while (cin >> n >> m && (n || m)) { - for (int i = 0; i < n; ++i) - graph[i].clear(); - - for (int i = 0; i < m; ++i) { - int x, y; cin >> x >> y; - x--, y--; - graph[x].pb(y); - graph[y].pb(x); - } - - tarjan(0); - cout << "Teste " << cas << ende; - if (!articulations.size()) - cout << "nenhum" << ende; - else { - for (auto i : articulations) - cout << i + 1 << " "; - cout << ende; + ios::sync_with_stdio(0); + cin.tie(0); + + int n, m; + int cas = 1; + while (cin >> n >> m && (n || m)) { + for (int i = 0; i < n; ++i) + graph[i].clear(); + + for (int i = 0; i < m; ++i) { + int x, y; cin >> x >> y; + x--, y--; + graph[x].pb(y); + graph[y].pb(x); + } + + tarjan(0); + cout << "Teste " << cas << ende; + if (!articulations.size()) + cout << "nenhum" << ende; + else { + for (auto i : articulations) + cout << i + 1 << " "; + cout << ende; + } + + cas++; + cout << ende; } - cas++; - cout << ende; - } - - return 0; + return 0; } diff --git a/contests/Cadernaveis/MCAIRO.cpp b/contests/Cadernaveis/MCAIRO.cpp index 74c43a0cdbb2f5bf374077164c7fc9bc9cb4fc12..d6e5a4ee0ed0dd92664e1c354fd553c8b60fbab5 100644 --- a/contests/Cadernaveis/MCAIRO.cpp +++ b/contests/Cadernaveis/MCAIRO.cpp @@ -22,50 +22,50 @@ using ll = long long; using ii = pair<int,int>; struct BIT2D { - int N, M; - vector<vector<int>> tree; - - BIT2D(int N, int M) : - N(N), M(M), tree(N, vector<int>(M)) - { init(); } - - void init() { - for (auto &i : tree) - fill(all(i), 0); - } - - int query(int idx, int idy) { - int sum = 0; - for (; idx > 0; idx -= (idx & -idx)) - for (int m = idy; m > 0; m -= (m & -m)) - sum = max(sum, tree[idx][m]); - return sum; - } - - void update(int idx, int idy, int val) { - for (; idx < N; idx += (idx & -idx)) - for (int m = idy; m < M; m += (m & -m)) - tree[idx][m] = max(tree[idx][m], val); - } + int N, M; + vector<vector<int>> tree; + + BIT2D(int N, int M) : + N(N), M(M), tree(N, vector<int>(M)) + { init(); } + + void init() { + for (auto &i : tree) + fill(all(i), 0); + } + + int query(int idx, int idy) { + int sum = 0; + for (; idx > 0; idx -= (idx & -idx)) + for (int m = idy; m > 0; m -= (m & -m)) + sum = max(sum, tree[idx][m]); + return sum; + } + + void update(int idx, int idy, int val) { + for (; idx < N; idx += (idx & -idx)) + for (int m = idy; m < M; m += (m & -m)) + tree[idx][m] = max(tree[idx][m], val); + } }; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int t; cin >> t; - for (int cas = 1; cas <= t; ++cas) { - BIT2D bit(1001, 1001); + int t; cin >> t; + for (int cas = 1; cas <= t; ++cas) { + BIT2D bit(1001, 1001); - int n; cin >> n; - vector<int> x(n), y(n); - for (int i = 0; i < n; ++i) - cin >> x[i] >> y[i]; + int n; cin >> n; + vector<int> x(n), y(n); + for (int i = 0; i < n; ++i) + cin >> x[i] >> y[i]; - for (int i = 0; i < n; ++i) - bit.update(x[i], y[i], 1 + bit.query(x[i], y[i])); - cout << bit.query(1000, 1000) << ende; - } + for (int i = 0; i < n; ++i) + bit.update(x[i], y[i], 1 + bit.query(x[i], y[i])); + cout << bit.query(1000, 1000) << ende; + } - return 0; + return 0; } diff --git a/contests/Cadernaveis/NTICKETS.cpp b/contests/Cadernaveis/NTICKETS.cpp index 46ca3dd751d0dee0f4b5749900443a232bae19bd..d25db6faf4b13497831d866a55060aecdb952102 100644 --- a/contests/Cadernaveis/NTICKETS.cpp +++ b/contests/Cadernaveis/NTICKETS.cpp @@ -30,86 +30,86 @@ ll h[MAX]; ll par[MAX][MAXLOG], cost[MAX][MAXLOG]; void dfs(int v, int p = -1, ll c = 0) { - par[v][0] = p; - cost[v][0] = c; + par[v][0] = p; + cost[v][0] = c; - if (p + 1) - h[v] = h[p] + 1; + if (p + 1) + h[v] = h[p] + 1; - for (int i = 1; i < MAXLOG; ++i) - if (par[v][i - 1] + 1) { - par[v][i] = par[par[v][i - 1]][i - 1]; - cost[v][i] = max(cost[v][i], max(cost[par[v][i-1]][i-1], cost[v][i-1])); - } + for (int i = 1; i < MAXLOG; ++i) + if (par[v][i - 1] + 1) { + par[v][i] = par[par[v][i - 1]][i - 1]; + cost[v][i] = max(cost[v][i], max(cost[par[v][i-1]][i-1], cost[v][i-1])); + } - for (auto u : graph[v]) - if (p != u.fi) - dfs(u.fi, v, u.se); + for (auto u : graph[v]) + if (p != u.fi) + dfs(u.fi, v, u.se); } void preprocess(int v) { - memset(par, -1, sizeof par); - memset(cost, 0, sizeof cost); - dfs(v); + memset(par, -1, sizeof par); + memset(cost, 0, sizeof cost); + dfs(v); } ll query(int p, int q) { - ll ans = 0; + ll ans = 0; - if (h[p] < h[q]) - swap(p, q); + if (h[p] < h[q]) + swap(p, q); - for (int i = MAXLOG - 1; i >= 0; --i) - if (par[p][i] + 1 && h[par[p][i]] >= h[q]) { - ans = max(ans, cost[p][i]); - p = par[p][i]; - } + for (int i = MAXLOG - 1; i >= 0; --i) + if (par[p][i] + 1 && h[par[p][i]] >= h[q]) { + ans = max(ans, cost[p][i]); + p = par[p][i]; + } - if (p == q) - return ans; + if (p == q) + return ans; - for (int i = MAXLOG - 1; i >= 0; --i) - if (par[p][i] + 1 && par[p][i] != par[q][i]) { - ans = max(ans, max(cost[p][i], cost[q][i])); - p = par[p][i]; - q = par[q][i]; - } + for (int i = MAXLOG - 1; i >= 0; --i) + if (par[p][i] + 1 && par[p][i] != par[q][i]) { + ans = max(ans, max(cost[p][i], cost[q][i])); + p = par[p][i]; + q = par[q][i]; + } - if (p == q) return ans; - else return max(ans, max(cost[p][0], cost[q][0])); + if (p == q) return ans; + else return max(ans, max(cost[p][0], cost[q][0])); } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, a, b; - ll t; - - while (cin >> n && n) { - for (int i = 0; i <= n; ++i) - graph[i].clear(); - - for (int i = 0; i < n - 1; ++i) { - cin >> a >> b >> t; - a--, b--; - graph[a].pb(ii(b, t)); - graph[b].pb(ii(a, t)); - } - - int q; - preprocess(0); - - cin >> q; - for (int i = 0; i < q; ++i) { - cin >> a >> b; - a--, b--; - cout << query(a, b) << '\n'; + ios::sync_with_stdio(0); + cin.tie(0); + + int n, a, b; + ll t; + + while (cin >> n && n) { + for (int i = 0; i <= n; ++i) + graph[i].clear(); + + for (int i = 0; i < n - 1; ++i) { + cin >> a >> b >> t; + a--, b--; + graph[a].pb(ii(b, t)); + graph[b].pb(ii(a, t)); + } + + int q; + preprocess(0); + + cin >> q; + for (int i = 0; i < q; ++i) { + cin >> a >> b; + a--, b--; + cout << query(a, b) << '\n'; + } + cout << '\n'; } - cout << '\n'; - } - return 0; + return 0; } diff --git a/contests/Cadernaveis/ORKUT.cpp b/contests/Cadernaveis/ORKUT.cpp index 52f79016fc6c1a174a0b8109e90fbbf7e2072cc3..97d19cf481c72f9cc41e3660207f3913d8faeb6a 100644 --- a/contests/Cadernaveis/ORKUT.cpp +++ b/contests/Cadernaveis/ORKUT.cpp @@ -25,94 +25,94 @@ using ii = pair<int,int>; vector<int> graph[MAX]; struct TopologicalSort { - int N; - stack<int> S; - vector<int> cont; - - TopologicalSort(int N) : - N(N), cont(N) - {} - - void init() { - fill(all(cont), 0); - } - - bool dfs(int x) { - cont[x] = 1; - - for (auto i : graph[x]) { - if (cont[i] == 1) - return true; - if (!cont[i] && dfs(i)) - return true; + int N; + stack<int> S; + vector<int> cont; + + TopologicalSort(int N) : + N(N), cont(N) + {} + + void init() { + fill(all(cont), 0); } - cont[x] = 2; - S.push(x); + bool dfs(int x) { + cont[x] = 1; - return false; - } + for (auto i : graph[x]) { + if (cont[i] == 1) + return true; + if (!cont[i] && dfs(i)) + return true; + } - bool run(vector<int> &tsort) { - init(); + cont[x] = 2; + S.push(x); - bool cycle = false; - for (int i = 0; i < N; ++i) { - if (!cont[i]) - cycle |= dfs(i); + return false; } - if (cycle) - return true; + bool run(vector<int> &tsort) { + init(); - while (!S.empty()) { - tsort.pb(S.top()); - S.pop(); - } + bool cycle = false; + for (int i = 0; i < N; ++i) { + if (!cont[i]) + cycle |= dfs(i); + } - return false; - } -}; + if (cycle) + return true; -int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n; - for (int cas = 1; cin >> n && n; ++cas) { - for (int i = 0; i < MAX; ++i) - graph[i].clear(); - - vector<string> v(n); - map<string,int> M; - for (int i = 0; i < n; ++i) { - cin >> v[i]; - M[v[i]] = i; - } + while (!S.empty()) { + tsort.pb(S.top()); + S.pop(); + } - for (int i = 0; i < n; ++i) { - string a; cin >> a; - int m; cin >> m; - for (int j = 0; j < m; ++j) { - string b; cin >> b; - graph[M[b]].pb(M[a]); - } + return false; } +}; - TopologicalSort ts(n); - vector<int> ans; - bool cycle = ts.run(ans); - - cout << "Teste " << cas << ende; - if (cycle) - cout << "impossivel" << ende; - else { - for (auto i : ans) - cout << v[i] << " "; - cout << ende; +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + int n; + for (int cas = 1; cin >> n && n; ++cas) { + for (int i = 0; i < MAX; ++i) + graph[i].clear(); + + vector<string> v(n); + map<string,int> M; + for (int i = 0; i < n; ++i) { + cin >> v[i]; + M[v[i]] = i; + } + + for (int i = 0; i < n; ++i) { + string a; cin >> a; + int m; cin >> m; + for (int j = 0; j < m; ++j) { + string b; cin >> b; + graph[M[b]].pb(M[a]); + } + } + + TopologicalSort ts(n); + vector<int> ans; + bool cycle = ts.run(ans); + + cout << "Teste " << cas << ende; + if (cycle) + cout << "impossivel" << ende; + else { + for (auto i : ans) + cout << v[i] << " "; + cout << ende; + } + cout << ende; } - cout << ende; - } - return 0; + return 0; } diff --git a/contests/Cadernaveis/TOPOLAND.cpp b/contests/Cadernaveis/TOPOLAND.cpp index 8b8b1bf7387c676c8b836e108a45b2cafb9a1fb1..fbdb9a381a8314f885a639e7e155bd3d63a79d23 100644 --- a/contests/Cadernaveis/TOPOLAND.cpp +++ b/contests/Cadernaveis/TOPOLAND.cpp @@ -26,84 +26,84 @@ typedef pair<int,int> ii; ll N, tree[4 * MAX], v[MAX]; void build_tree(int node = 1, int a = 0, int b = N) { - if (a > b) - return; + if (a > b) + return; - if (a == b) { - tree[node] = v[a]; - return; - } + if (a == b) { + tree[node] = v[a]; + return; + } - build_tree(node * 2, a, (a + b) / 2); - build_tree(node * 2 + 1, 1 + (a + b) / 2, b); + build_tree(node * 2, a, (a + b) / 2); + build_tree(node * 2 + 1, 1 + (a + b) / 2, b); - tree[node] = max(tree[node * 2], tree[node * 2 + 1]); + tree[node] = max(tree[node * 2], tree[node * 2 + 1]); } void update_tree(int idx, ll val, int node = 1, int a = 0, int b = N) { - if (a > b || a > idx || b < idx) - return; + if (a > b || a > idx || b < idx) + return; - if (a == b) { - tree[node] = val; - return; - } + if (a == b) { + tree[node] = val; + return; + } - update_tree(idx, val, node * 2, a, (a + b) / 2); - update_tree(idx, val, node * 2 + 1, 1 + (a + b) / 2, b); + update_tree(idx, val, node * 2, a, (a + b) / 2); + update_tree(idx, val, node * 2 + 1, 1 + (a + b) / 2, b); - tree[node] = max(tree[node * 2], tree[node * 2 + 1]); + tree[node] = max(tree[node * 2], tree[node * 2 + 1]); } int query_tree(int i, int j, int node = 1, int a = 0, int b = N) { - if (a > b || a > j || b < i) - return 0; + if (a > b || a > j || b < i) + return 0; - if (a >= i && b <= j) - return tree[node]; + if (a >= i && b <= j) + return tree[node]; - int res1 = query_tree(i, j, node * 2, a, (a + b) / 2); - int res2 = query_tree(i, j, node * 2 + 1, 1 + (a + b) / 2, b); + int res1 = query_tree(i, j, node * 2, a, (a + b) / 2); + int res2 = query_tree(i, j, node * 2 + 1, 1 + (a + b) / 2, b); - return max(res1, res2); + return max(res1, res2); } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - ll t, n, m; - cin >> t; - for (int cas = 0; cas < t; ++cas) { - cout << "Testcase " << cas << ":\n"; - cin >> n >> m; - N = n; - - for (int i = 0; i < n; ++i) - cin >> v[i]; - build_tree(); - - ll q, a, b; - string op; - cin >> q; - for (int i = 0; i < q; ++i) { - cin >> op; - if (op[0] == 'A') { - cin >> a; - m += a; - } else if (op[0] == 'B') { - cin >> a >> b; - update_tree(a, b); - } else { - cin >> a >> b; - cout << abs(m - query_tree(a, b)) << '\n'; - } + ios::sync_with_stdio(0); + cin.tie(0); + + ll t, n, m; + cin >> t; + for (int cas = 0; cas < t; ++cas) { + cout << "Testcase " << cas << ":\n"; + cin >> n >> m; + N = n; + + for (int i = 0; i < n; ++i) + cin >> v[i]; + build_tree(); + + ll q, a, b; + string op; + cin >> q; + for (int i = 0; i < q; ++i) { + cin >> op; + if (op[0] == 'A') { + cin >> a; + m += a; + } else if (op[0] == 'B') { + cin >> a >> b; + update_tree(a, b); + } else { + cin >> a >> b; + cout << abs(m - query_tree(a, b)) << '\n'; + } + } + cout << '\n'; } - cout << '\n'; - } - return 0; + return 0; } diff --git a/contests/Cadernaveis/TUBOS.cpp b/contests/Cadernaveis/TUBOS.cpp index 7a6307bb209ecb39679d4e556c7b361a4b54fb97..1313f076d963f6936638829134f4427da7819c54 100644 --- a/contests/Cadernaveis/TUBOS.cpp +++ b/contests/Cadernaveis/TUBOS.cpp @@ -30,54 +30,54 @@ int low[MAX]; vector<ii> bridges; void dfs(int x) { - int child = 0; - visited[x] = 1; + int child = 0; + visited[x] = 1; - for (auto i : graph[x]) { - if (!visited[i]) { - child++; - parent[i] = x; + for (auto i : graph[x]) { + if (!visited[i]) { + child++; + parent[i] = x; - low[i] = L[i] = L[x] + 1; - dfs(i); + low[i] = L[i] = L[x] + 1; + dfs(i); - low[x] = min(low[x], low[i]); + low[x] = min(low[x], low[i]); - if (low[i] > L[x]) - bridges.pb(ii(x, i)); + if (low[i] > L[x]) + bridges.pb(ii(x, i)); - } else if (parent[x] != i) - low[x] = min(low[x], L[i]); - } + } else if (parent[x] != i) + low[x] = min(low[x], L[i]); + } } void tarjan(int n) { - mset(visited, 0); - mset(parent, -1); - mset(L, 0); - bridges.clear(); - dfs(n); + mset(visited, 0); + mset(parent, -1); + mset(L, 0); + bridges.clear(); + dfs(n); } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, m; - while (cin >> n >> m && (n || m)) { - for (int i = 0; i < n; ++i) - graph[i].clear(); - - for (int i = 0; i < m; ++i) { - int x, y; cin >> x >> y; - x--, y--; - graph[x].pb(y); - graph[y].pb(x); + ios::sync_with_stdio(0); + cin.tie(0); + + int n, m; + while (cin >> n >> m && (n || m)) { + for (int i = 0; i < n; ++i) + graph[i].clear(); + + for (int i = 0; i < m; ++i) { + int x, y; cin >> x >> y; + x--, y--; + graph[x].pb(y); + graph[y].pb(x); + } + + tarjan(0); + cout << (bridges.size() ? "N" : "S") << ende; } - tarjan(0); - cout << (bridges.size() ? "N" : "S") << ende; - } - - return 0; + return 0; } diff --git a/contests/Cadernaveis/URI1033.cpp b/contests/Cadernaveis/URI1033.cpp index 11d69a4b108650fe8f8ba94a8859899305c220d4..7221c522b9cf4a5fca57f70f6ef85026f206993f 100644 --- a/contests/Cadernaveis/URI1033.cpp +++ b/contests/Cadernaveis/URI1033.cpp @@ -22,79 +22,79 @@ typedef unsigned long long ll; typedef pair<int,int> ii; struct matrix { - int N; - ll b; - vector<vector<ll>> m; - - matrix(int N, ll b) : N(N), b(b) { - m = vector<vector<ll>>(N, vector<ll>(N, 0)); - } - - matrix operator*(matrix a) { - matrix res(N, b); - for (int i = 0; i < N; i++) - for (int j = 0; j < N; j++) { - res[i][j] = 0; - - for (int k = 0; k < N; k++) - res[i][j] = (((m[i][k] * a[k][j]) % b) + res[i][j]) % b; - } - - return res; - } - - void to_identity() { - for (auto &i : m) - fill(all(i), 0); - for (int i = 0; i < N; ++i) - m[i][i] = 1; - } - - vector<ll> &operator[](int i) { - return m[i]; - } + int N; + ll b; + vector<vector<ll>> m; + + matrix(int N, ll b) : N(N), b(b) { + m = vector<vector<ll>>(N, vector<ll>(N, 0)); + } + + matrix operator*(matrix a) { + matrix res(N, b); + for (int i = 0; i < N; i++) + for (int j = 0; j < N; j++) { + res[i][j] = 0; + + for (int k = 0; k < N; k++) + res[i][j] = (((m[i][k] * a[k][j]) % b) + res[i][j]) % b; + } + + return res; + } + + void to_identity() { + for (auto &i : m) + fill(all(i), 0); + for (int i = 0; i < N; ++i) + m[i][i] = 1; + } + + vector<ll> &operator[](int i) { + return m[i]; + } }; ll fast_pow(matrix in, ll n, ll b) { - matrix ans(2, b); - ans.to_identity(); + matrix ans(2, b); + ans.to_identity(); - while (n) { - if (n & 1) - ans = ans * in; + while (n) { + if (n & 1) + ans = ans * in; - n >>= 1; - in = in * in; - } + n >>= 1; + in = in * in; + } - return ans[0][0]; + return ans[0][0]; } ll solve(ll n, ll b) { - matrix in(2, b); + matrix in(2, b); - in[0][0] = 1; - in[0][1] = 1; + in[0][0] = 1; + in[0][1] = 1; - in[1][0] = 1; - in[1][1] = 0; + in[1][0] = 1; + in[1][1] = 0; - return fast_pow(in, n, b); + return fast_pow(in, n, b); } int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - ll n, b; - int cas = 1; - while (cin >> n >> b && (n || b)) { - ll ans = solve(n, b) % b; - ans = (ans + ans) % b; - ans = (ans - 1 + b) % b; + ll n, b; + int cas = 1; + while (cin >> n >> b && (n || b)) { + ll ans = solve(n, b) % b; + ans = (ans + ans) % b; + ans = (ans - 1 + b) % b; - cout << "Case " << cas++ << ":" << " " << n << " " << b << " " << ans << ende; - } + cout << "Case " << cas++ << ":" << " " << n << " " << b << " " << ans << ende; + } - return 0; + return 0; } diff --git a/contests/Cadernaveis/URI1128.cpp b/contests/Cadernaveis/URI1128.cpp index 4d8c55b48bd7e668614668255d53ad5d3f4845cd..251641fd19126fd2fa931f00599f6db77a12b3d6 100644 --- a/contests/Cadernaveis/URI1128.cpp +++ b/contests/Cadernaveis/URI1128.cpp @@ -35,71 +35,71 @@ int low[MAX]; vector<int> scc[MAX]; void dfs(int x) { - id[x] = low[x] = ind++; - visited[x] = 1; + id[x] = low[x] = ind++; + visited[x] = 1; - S.push(x); + S.push(x); - for (auto i : graph[x]) - if (id[i] == -1) { - dfs(i); + for (auto i : graph[x]) + if (id[i] == -1) { + dfs(i); - low[x] = min(low[x], low[i]); + low[x] = min(low[x], low[i]); - } else if (visited[i]) - low[x] = min(low[x], id[i]); + } else if (visited[i]) + low[x] = min(low[x], id[i]); - if (low[x] == id[x]) { - int w; + if (low[x] == id[x]) { + int w; - do { - w = S.top(); S.pop(); - visited[w] = 0; - scc[ncomp].pb(w); - } while (w != x); + do { + w = S.top(); S.pop(); + visited[w] = 0; + scc[ncomp].pb(w); + } while (w != x); - ncomp++; - } + ncomp++; + } } int tarjan(int n) { - mset(id, -1); - ncomp = ind = 0; + mset(id, -1); + ncomp = ind = 0; - for (int i = 0; i < n; ++i) - scc[i].clear(); + for (int i = 0; i < n; ++i) + scc[i].clear(); - for (int i = 0; i < n; ++i) - if (id[i] == -1) - dfs(i); + for (int i = 0; i < n; ++i) + if (id[i] == -1) + dfs(i); - return ncomp; + return ncomp; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, m; - while (cin >> n >> m && (n || m)) { - for (int i = 0; i < n; ++i) - graph[i].clear(); - - for (int i = 0; i < m; ++i) { - int v, w, p; cin >> v >> w >> p; - v--, w--; - if (p == 1) - graph[v].pb(w); - else { - graph[v].pb(w); - graph[w].pb(v); - } + ios::sync_with_stdio(0); + cin.tie(0); + + int n, m; + while (cin >> n >> m && (n || m)) { + for (int i = 0; i < n; ++i) + graph[i].clear(); + + for (int i = 0; i < m; ++i) { + int v, w, p; cin >> v >> w >> p; + v--, w--; + if (p == 1) + graph[v].pb(w); + else { + graph[v].pb(w); + graph[w].pb(v); + } + } + + int ans = tarjan(n); + cout << (ans == 1) << ende; } - int ans = tarjan(n); - cout << (ans == 1) << ende; - } - - return 0; + return 0; } diff --git a/contests/Cadernaveis/URI1130.cpp b/contests/Cadernaveis/URI1130.cpp index 3b235dd6d4e203de06fd92f7d652a434898e19e2..d04e4a8239d14173b19463cb17f4e57c435f1b4a 100644 --- a/contests/Cadernaveis/URI1130.cpp +++ b/contests/Cadernaveis/URI1130.cpp @@ -25,54 +25,54 @@ using ii = pair<int,int>; int dp[MAX]; int solve(int n) { - if (n < 5) return 0; - if (dp[n] != -1) return dp[n]; - - vector<int> foi(MAX, 0); - for (int i = 2; i < n - 2; ++i) - foi[solve(i) ^ solve(n - i - 1)] = 1; - - for (int i = 0; i < MAX; ++i) - if (!foi[i]) - return dp[n] = i; - - assert(false); - return -1; -} + if (n < 5) return 0; + if (dp[n] != -1) return dp[n]; -int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n; - mset(dp, -1); - while (cin >> n && n) { - string s; cin >> s; - - bool poss = false; - for (int i = 0; i < n - 1; ++i) - poss |= (s[i] == 'X' && s[i+1] == 'X'); - for (int i = 0; i < n - 2; ++i) - poss |= (s[i] == 'X' && s[i+2] == 'X'); - - if (poss) { - cout << 'S' << ende; - continue; - } + vector<int> foi(MAX, 0); + for (int i = 2; i < n - 2; ++i) + foi[solve(i) ^ solve(n - i - 1)] = 1; - int last = -1, ans = 0; - for (int i = 0; i < n; ++i) - if (s[i] == 'X') { - if (last == -1) ans ^= solve(2 + i); - else ans ^= solve(i - last - 1); - last = i; - } + for (int i = 0; i < MAX; ++i) + if (!foi[i]) + return dp[n] = i; - if (last == -1) ans ^= solve(2 + n + 2); - else ans ^= solve((n - last - 1) + 2); + assert(false); + return -1; +} - cout << (ans ? 'S' : 'N') << ende; - } +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + int n; + mset(dp, -1); + while (cin >> n && n) { + string s; cin >> s; + + bool poss = false; + for (int i = 0; i < n - 1; ++i) + poss |= (s[i] == 'X' && s[i+1] == 'X'); + for (int i = 0; i < n - 2; ++i) + poss |= (s[i] == 'X' && s[i+2] == 'X'); + + if (poss) { + cout << 'S' << ende; + continue; + } + + int last = -1, ans = 0; + for (int i = 0; i < n; ++i) + if (s[i] == 'X') { + if (last == -1) ans ^= solve(2 + i); + else ans ^= solve(i - last - 1); + last = i; + } + + if (last == -1) ans ^= solve(2 + n + 2); + else ans ^= solve((n - last - 1) + 2); + + cout << (ans ? 'S' : 'N') << ende; + } - return 0; + return 0; } diff --git a/contests/Cadernaveis/URI1135.cpp b/contests/Cadernaveis/URI1135.cpp index a0395db5f37a3148cc63458ea8d2f98960be04df..8b3409da2426ffba693a93df56ea1845b05cad09 100644 --- a/contests/Cadernaveis/URI1135.cpp +++ b/contests/Cadernaveis/URI1135.cpp @@ -30,81 +30,81 @@ ll h[MAX]; ll par[MAX][MAXLOG], cost[MAX][MAXLOG]; void dfs(int v, int p = -1, ll c = 0) { - par[v][0] = p; - cost[v][0] = c; + par[v][0] = p; + cost[v][0] = c; - if (p + 1) - h[v] = h[p] + 1; + if (p + 1) + h[v] = h[p] + 1; - for (int i = 1; i < MAXLOG; ++i) - if (par[v][i - 1] + 1) { - par[v][i] = par[par[v][i - 1]][i - 1]; - cost[v][i] += cost[v][i - 1] + cost[par[v][i - 1]][i - 1]; - } + for (int i = 1; i < MAXLOG; ++i) + if (par[v][i - 1] + 1) { + par[v][i] = par[par[v][i - 1]][i - 1]; + cost[v][i] += cost[v][i - 1] + cost[par[v][i - 1]][i - 1]; + } - for (auto u : graph[v]) - if (p != u.fi) - dfs(u.fi, v, u.se); + for (auto u : graph[v]) + if (p != u.fi) + dfs(u.fi, v, u.se); } void preprocess(int v) { - memset(par, -1, sizeof par); - memset(cost, 0, sizeof cost); - dfs(v); + memset(par, -1, sizeof par); + memset(cost, 0, sizeof cost); + dfs(v); } ll query(int p, int q) { - ll ans = 0; + ll ans = 0; - if (h[p] < h[q]) - swap(p, q); + if (h[p] < h[q]) + swap(p, q); - for (int i = MAXLOG - 1; i >= 0; --i) - if (par[p][i] + 1 && h[par[p][i]] >= h[q]) { - ans += cost[p][i]; - p = par[p][i]; - } + for (int i = MAXLOG - 1; i >= 0; --i) + if (par[p][i] + 1 && h[par[p][i]] >= h[q]) { + ans += cost[p][i]; + p = par[p][i]; + } - if (p == q) - return ans; + if (p == q) + return ans; - for (int i = MAXLOG - 1; i >= 0; --i) - if (par[p][i] + 1 && par[p][i] != par[q][i]) { - ans += cost[p][i] + cost[q][i]; - p = par[p][i]; - q = par[q][i]; - } + for (int i = MAXLOG - 1; i >= 0; --i) + if (par[p][i] + 1 && par[p][i] != par[q][i]) { + ans += cost[p][i] + cost[q][i]; + p = par[p][i]; + q = par[q][i]; + } - if (p == q) return ans; - else return ans + cost[p][0] + cost[q][0]; + if (p == q) return ans; + else return ans + cost[p][0] + cost[q][0]; } int main() { - ll li; - int ai, n; - int q, s, t; - - while (scanf("%d", &n) && n) { - for (int i = 0; i < n + 1; ++i) - graph[i].clear(); - - for (int i = 1; i <= n - 1; ++i) { - scanf("%d %lld", &ai, &li); - graph[ai].pb(ii(i, li)); - } - - preprocess(0); - - scanf("%d", &q); - for (int i = 0; i < q; ++i) { - scanf("%d %d", &s, &t); - if (i) printf(" "); - printf("%lld", query(s, t)); + ll li; + int ai, n; + int q, s, t; + + while (scanf("%d", &n) && n) { + for (int i = 0; i < n + 1; ++i) + graph[i].clear(); + + for (int i = 1; i <= n - 1; ++i) { + scanf("%d %lld", &ai, &li); + graph[ai].pb(ii(i, li)); + } + + preprocess(0); + + scanf("%d", &q); + for (int i = 0; i < q; ++i) { + scanf("%d %d", &s, &t); + if (i) printf(" "); + printf("%lld", query(s, t)); + } + printf("\n"); } - printf("\n"); - } - return 0; + return 0; } diff --git a/contests/Cadernaveis/URI1141.cpp b/contests/Cadernaveis/URI1141.cpp index 395917ee6f96616cc027d0a07cc8628f669f9af0..a0440b9e60c734769c74615a29647e593b7dd61f 100644 --- a/contests/Cadernaveis/URI1141.cpp +++ b/contests/Cadernaveis/URI1141.cpp @@ -22,64 +22,64 @@ using ll = long long; using ii = pair<int,int>; struct AhoCorasick { - struct Node { - int fail, occ; - vector<int> words; - map<char,int> next; - - Node() : fail(0), occ(-1) {} - int has(char i) { return next.count(i); } - int &operator[](char i) { return next[i]; } - }; - - vector<Node> trie; - - AhoCorasick(const vector<string> &v) { - trie.pb(Node()); - build(v); - preprocess(); - } - - int insert(const string &s) { - int n = 0; - for (int i = 0; i < s.size(); n = trie[n][s[i]], ++i) - if (!trie[n].has(s[i])) { - trie[n][s[i]] = trie.size(); + struct Node { + int fail, occ; + vector<int> words; + map<char,int> next; + + Node() : fail(0), occ(-1) {} + int has(char i) { return next.count(i); } + int &operator[](char i) { return next[i]; } + }; + + vector<Node> trie; + + AhoCorasick(const vector<string> &v) { trie.pb(Node()); - } - return n; - } - - void build(const vector<string> &v) { - for (int i = 0; i < v.size(); ++i) { - int n = insert(v[i]); - trie[n].words.pb(i); + build(v); + preprocess(); } - } - - inline int suffix(int v, char c) { - while (v != 0 && !trie[v].has(c)) v = trie[v].fail; - if (trie[v].has(c)) v = trie[v][c]; - return v; - } - - void preprocess() { - vector<int> Q = { 0 }; - for (int i = 0; i != Q.size(); ++i) { - int u = Q[i]; - for (auto j : trie[u].next) { - int &v = trie[j.se].fail; - if (u) { - v = suffix(trie[u].fail, j.fi); - trie[j.se].occ = trie[v].words.size() ? v : trie[v].occ; - } else { - v = trie[u].fail; - trie[j.se].occ = -1; + + int insert(const string &s) { + int n = 0; + for (int i = 0; i < s.size(); n = trie[n][s[i]], ++i) + if (!trie[n].has(s[i])) { + trie[n][s[i]] = trie.size(); + trie.pb(Node()); + } + return n; + } + + void build(const vector<string> &v) { + for (int i = 0; i < v.size(); ++i) { + int n = insert(v[i]); + trie[n].words.pb(i); + } + } + + inline int suffix(int v, char c) { + while (v != 0 && !trie[v].has(c)) v = trie[v].fail; + if (trie[v].has(c)) v = trie[v][c]; + return v; + } + + void preprocess() { + vector<int> Q = { 0 }; + for (int i = 0; i != Q.size(); ++i) { + int u = Q[i]; + for (auto j : trie[u].next) { + int &v = trie[j.se].fail; + if (u) { + v = suffix(trie[u].fail, j.fi); + trie[j.se].occ = trie[v].words.size() ? v : trie[v].occ; + } else { + v = trie[u].fail; + trie[j.se].occ = -1; + } + Q.pb(j.se); + } } - Q.pb(j.se); - } } - } }; int n; @@ -87,41 +87,41 @@ int dp[10101]; vector<string> v; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - while (cin >> n && n) { - v.clear(); - v.resize(n); - for (auto &i : v) - cin >> i; - - sort(all(v), [](const string &a, const string &b) { - return a.size() > b.size(); - }); - - AhoCorasick aho(v); - for (int i = n - 1; i >= 0; --i) { - int grt = 0, u = 0; - for (auto j : v[i]) { - u = aho.suffix(u, j); - for (auto k : aho.trie[u].words) - if (k != i) - grt = max(grt, dp[k] + 1); - - int x = u; - while (aho.trie[x].occ != -1) { - x = aho.trie[x].occ; - for (auto k : aho.trie[x].words) - if (k != i) - grt = max(grt, dp[k] + 1); + ios::sync_with_stdio(0); + cin.tie(0); + + while (cin >> n && n) { + v.clear(); + v.resize(n); + for (auto &i : v) + cin >> i; + + sort(all(v), [](const string &a, const string &b) { + return a.size() > b.size(); + }); + + AhoCorasick aho(v); + for (int i = n - 1; i >= 0; --i) { + int grt = 0, u = 0; + for (auto j : v[i]) { + u = aho.suffix(u, j); + for (auto k : aho.trie[u].words) + if (k != i) + grt = max(grt, dp[k] + 1); + + int x = u; + while (aho.trie[x].occ != -1) { + x = aho.trie[x].occ; + for (auto k : aho.trie[x].words) + if (k != i) + grt = max(grt, dp[k] + 1); + } + } + dp[i] = grt; } - } - dp[i] = grt; - } - cout << (*max_element(dp, dp + n) + 1) << ende; - } + cout << (*max_element(dp, dp + n) + 1) << ende; + } - return 0; + return 0; } diff --git a/contests/Cadernaveis/URI1356.cpp b/contests/Cadernaveis/URI1356.cpp index a9936ab760ff724db1c6e67a1ac079cce4349c1c..839e8a9f3b9a79581d0851613709de5d9ef5eeeb 100644 --- a/contests/Cadernaveis/URI1356.cpp +++ b/contests/Cadernaveis/URI1356.cpp @@ -27,75 +27,75 @@ ll tree[MAX]; ll b, p, l, n; ll query(ll idx) { - ll sum = 0; - for (; idx > 0; idx -= (idx & -idx)) - sum = (sum + tree[idx] + p) % p; + ll sum = 0; + for (; idx > 0; idx -= (idx & -idx)) + sum = (sum + tree[idx] + p) % p; - return sum % p; + return sum % p; } void update(ll idx, ll val) { - for (; idx <= MAX; idx += (idx & -idx)) - tree[idx] = (tree[idx] + val + p) % p; + for (; idx <= MAX; idx += (idx & -idx)) + tree[idx] = (tree[idx] + val + p) % p; } ll power(ll x, ll y) { - ll ans = 1; + ll ans = 1; - while (y) { - if (y & 1) - ans = (ans * x) % p; + while (y) { + if (y & 1) + ans = (ans * x) % p; - y >>= 1; - x = (x * x) % p; - } + y >>= 1; + x = (x * x) % p; + } - return ans % p; + return ans % p; } ll mod_inverse(ll a) { - return power(a, p - 2); + return power(a, p - 2); } int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - while (cin >> b >> p >> l >> n && (b || p || l || n)) { - mset(tree, 0); + while (cin >> b >> p >> l >> n && (b || p || l || n)) { + mset(tree, 0); - vector<ll> powB(l + 1); powB[0] = 1; - for (int i = 1; i <= l; ++i) - powB[i] = (powB[i-1] * (b % p)) % p; + vector<ll> powB(l + 1); powB[0] = 1; + for (int i = 1; i <= l; ++i) + powB[i] = (powB[i-1] * (b % p)) % p; - for (int i = 0; i < n; ++i) { - string op; cin >> op; + for (int i = 0; i < n; ++i) { + string op; cin >> op; - if (op[0] == 'E') { - ll pos, val; cin >> pos >> val; + if (op[0] == 'E') { + ll pos, val; cin >> pos >> val; - // Remove current value from bit - update(pos, -((query(pos) - query(pos - 1) + p) % p)); + // Remove current value from bit + update(pos, -((query(pos) - query(pos - 1) + p) % p)); - // Insert new value into bit (val*b^(l-pos)) - update(pos, ((val % p) * powB[l - pos]) % p); - } else { - ll L, R; cin >> L >> R; + // Insert new value into bit (val*b^(l-pos)) + update(pos, ((val % p) * powB[l - pos]) % p); + } else { + ll L, R; cin >> L >> R; - // Get range sum - ll sum = (query(R) - query(L - 1) + p) % p; + // Get range sum + ll sum = (query(R) - query(L - 1) + p) % p; - // Result is (sum / b^(l-R)) % p - cout << (sum * mod_inverse(powB[l - R])) % p << ende; - } - } + // Result is (sum / b^(l-R)) % p + cout << (sum * mod_inverse(powB[l - R])) % p << ende; + } + } - cout << "-" << ende; - } + cout << "-" << ende; + } - return 0; + return 0; } diff --git a/contests/Cadernaveis/URI1364.cpp b/contests/Cadernaveis/URI1364.cpp index f3385d540f9a2b7d478217f0cf7da0573581089c..f07e730a0bbff709f51ff5300bf9aecb1a69d43d 100644 --- a/contests/Cadernaveis/URI1364.cpp +++ b/contests/Cadernaveis/URI1364.cpp @@ -23,39 +23,39 @@ typedef long long ll; typedef pair<int,int> ii; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, m; - while (cin >> n >> m && (n || m)) { - vector<string> emo(n); - for (auto &i : emo) cin >> i; - cin.ignore(); - - int ans = 0; - for (int i = 0; i < m; ++i) { - string s; - getline(cin, s); - - for (int j = 0; j < s.sz; ++j) { - for (int k = 0; k < n; ++k) { - if (s[j] == emo[k].back()) { - for (int l = j, ll = emo[k].sz - 1; ll >= 0 && l >= 0; ll--, l--) { - if (s[l] != emo[k][ll]) - break; - - if (ll == 0) { - s[j] = ' '; - ans++; - } + ios::sync_with_stdio(0); + cin.tie(0); + + int n, m; + while (cin >> n >> m && (n || m)) { + vector<string> emo(n); + for (auto &i : emo) cin >> i; + cin.ignore(); + + int ans = 0; + for (int i = 0; i < m; ++i) { + string s; + getline(cin, s); + + for (int j = 0; j < s.sz; ++j) { + for (int k = 0; k < n; ++k) { + if (s[j] == emo[k].back()) { + for (int l = j, ll = emo[k].sz - 1; ll >= 0 && l >= 0; ll--, l--) { + if (s[l] != emo[k][ll]) + break; + + if (ll == 0) { + s[j] = ' '; + ans++; + } + } + } + } } - } } - } - } - cout << ans << ende; - } + cout << ans << ende; + } - return 0; + return 0; } diff --git a/contests/Cadernaveis/URI1464.cpp b/contests/Cadernaveis/URI1464.cpp index cdb85804b58fbd2ca6832fa2be8650a241d01116..111241986965efd1302bcce72bf939831812a048 100644 --- a/contests/Cadernaveis/URI1464.cpp +++ b/contests/Cadernaveis/URI1464.cpp @@ -25,62 +25,62 @@ typedef pair<double,double> dd; double cross(dd a, dd b, dd c) { - return (b.fi - a.fi) * (c.se - a.se) - (b.se - a.se) * (c.fi - a.fi); + return (b.fi - a.fi) * (c.se - a.se) - (b.se - a.se) * (c.fi - a.fi); } int convex_hull(vector<dd> &v) { - int k = 0; - vector<int> ans(v.sz * 2); + int k = 0; + vector<int> ans(v.sz * 2); - sort(v.begin(), v.end(), [](const dd &a, const dd &b) -> bool { - return (a.fi == b.fi) ? (a.se < b.se) : (a.fi < b.fi); - }); + sort(v.begin(), v.end(), [](const dd &a, const dd &b) -> bool { + return (a.fi == b.fi) ? (a.se < b.se) : (a.fi < b.fi); + }); - for (int i = 0; i < v.sz; ++i) { - while (k >= 2 && cross(v[ans[k - 2]], v[ans[k - 1]], v[i]) < 0) k--; - ans[k++] = i; - } + for (int i = 0; i < v.sz; ++i) { + while (k >= 2 && cross(v[ans[k - 2]], v[ans[k - 1]], v[i]) < 0) k--; + ans[k++] = i; + } - for (int i = v.sz - 2, t = k + 1; i >= 0; --i) { - while (k >= t && cross(v[ans[k - 2]], v[ans[k - 1]], v[i]) < 0) k--; - ans[k++] = i; - } + for (int i = v.sz - 2, t = k + 1; i >= 0; --i) { + while (k >= t && cross(v[ans[k - 2]], v[ans[k - 1]], v[i]) < 0) k--; + ans[k++] = i; + } - ans.resize(k); - sort(rall(ans)); - ans.erase(unique(all(ans)), ans.end()); + ans.resize(k); + sort(rall(ans)); + ans.erase(unique(all(ans)), ans.end()); - for (auto i : ans) - v.erase(v.begin() + i); + for (auto i : ans) + v.erase(v.begin() + i); - return k - 1; + return k - 1; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n; - while (cin >> n && n) { - vector<dd> v; - double x, y; - - for (int i = 0; i < n; ++i) { - cin >> x >> y; - v.pb(dd(x, y)); + ios::sync_with_stdio(0); + cin.tie(0); + + int n; + while (cin >> n && n) { + vector<dd> v; + double x, y; + + for (int i = 0; i < n; ++i) { + cin >> x >> y; + v.pb(dd(x, y)); + } + + int ans = 0; + while (v.sz) { + convex_hull(v); + ans++; + } + + if (ans % 2) cout << "Take this onion to the lab!\n"; + else cout << "Do not take this onion to the lab!\n"; } - int ans = 0; - while (v.sz) { - convex_hull(v); - ans++; - } - - if (ans % 2) cout << "Take this onion to the lab!\n"; - else cout << "Do not take this onion to the lab!\n"; - } - - return 0; + return 0; } diff --git a/contests/Cadernaveis/URI1477.cpp b/contests/Cadernaveis/URI1477.cpp index 54df88c4241b4fa07fd76b3987218bcf39fbced6..c8816a961fdb3aa6e695daa66307527f6eeb79a8 100644 --- a/contests/Cadernaveis/URI1477.cpp +++ b/contests/Cadernaveis/URI1477.cpp @@ -24,27 +24,27 @@ typedef long long ll; typedef pair<int,int> ii; typedef struct elem { - int h, e, r; - - elem() : h(0), e(0), r(0) {} - elem(int h, int e, int r) : h(h), e(e), r(r) {} - - elem operator+(const elem &x) { - return elem(h + x.h, e + x.e, r + x.r); - } - - void change(int n) { - int a = h, b = e, c = r; - if (n % 3 == 1) { - e = a; - r = b; - h = c; - } else if (n % 3 == 2) { - e = c; - r = a; - h = b; + int h, e, r; + + elem() : h(0), e(0), r(0) {} + elem(int h, int e, int r) : h(h), e(e), r(r) {} + + elem operator+(const elem &x) { + return elem(h + x.h, e + x.e, r + x.r); + } + + void change(int n) { + int a = h, b = e, c = r; + if (n % 3 == 1) { + e = a; + r = b; + h = c; + } else if (n % 3 == 2) { + e = c; + r = a; + h = b; + } } - } } elem; @@ -57,97 +57,97 @@ int lazy[MAX * 4]; #define right(x) ((x << 1) + 1) void build(int node = 1, int a = 0, int b = N - 1) { - if (a > b) - return; + if (a > b) + return; - if (a == b) { - tree[node] = v[a]; - return; - } + if (a == b) { + tree[node] = v[a]; + return; + } - build(left(node), a, (a + b) / 2); - build(right(node), (a + b) / 2 + 1, b); - tree[node] = tree[node * 2] + tree[node * 2 + 1]; + build(left(node), a, (a + b) / 2); + build(right(node), (a + b) / 2 + 1, b); + tree[node] = tree[node * 2] + tree[node * 2 + 1]; } void push(int node, int a, int b, int val) { - tree[node].change(val); + tree[node].change(val); - if (a != b) { - lazy[left(node)] += val; - lazy[right(node)] += val; - } + if (a != b) { + lazy[left(node)] += val; + lazy[right(node)] += val; + } - lazy[node] = 0; + lazy[node] = 0; } void update(int i, int j, int node = 1, int a = 0, int b = N - 1) { - if (lazy[node] != 0) - push(node, a, b, lazy[node]); + if (lazy[node] != 0) + push(node, a, b, lazy[node]); - if (a > b or a > j or b < i) - return; + if (a > b or a > j or b < i) + return; - if (a >= i and b <= j) { - push(node, a, b, 1); - return; - } + if (a >= i and b <= j) { + push(node, a, b, 1); + return; + } - update(i, j, left(node), a, (a + b) / 2); - update(i, j, right(node), (a + b) / 2 + 1, b); - tree[node] = tree[node * 2] + tree[node * 2 + 1]; + update(i, j, left(node), a, (a + b) / 2); + update(i, j, right(node), (a + b) / 2 + 1, b); + tree[node] = tree[node * 2] + tree[node * 2 + 1]; } elem query(int i, int j, int node = 1, int a = 0, int b = N - 1) { - if (a > b || a > j || b < i) - return elem(); + if (a > b || a > j || b < i) + return elem(); - if (lazy[node]) - push(node, a, b, lazy[node]); + if (lazy[node]) + push(node, a, b, lazy[node]); - if (a >= i and b <= j) - return tree[node]; + if (a >= i and b <= j) + return tree[node]; - elem q1 = query(i, j, left(node), a, (a + b) / 2); - elem q2 = query(i, j, right(node), (a + b) / 2 + 1, b); - return q1 + q2; + elem q1 = query(i, j, left(node), a, (a + b) / 2); + elem q2 = query(i, j, right(node), (a + b) / 2 + 1, b); + return q1 + q2; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int m; - while (cin >> N >> m) { - for (int i = 0; i < MAX * 4; ++i) { - tree[i] = elem(); - lazy[i] = 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int m; + while (cin >> N >> m) { + for (int i = 0; i < MAX * 4; ++i) { + tree[i] = elem(); + lazy[i] = 0; + } + + for (int i = 0; i < N; ++i) { + v[i].h = 1; + v[i].e = v[i].r = 0; + } + + build(); + + for (int i = 0; i < m; ++i) { + char op; + int a, b; cin >> op >> a >> b; + + if (op == 'C') { + elem x = query(a - 1, b - 1); + cout << x.h << " " << x.e << " " << x.r << ende; + } else + update(a - 1, b - 1); + } + + cout << ende; } - for (int i = 0; i < N; ++i) { - v[i].h = 1; - v[i].e = v[i].r = 0; - } - - build(); - - for (int i = 0; i < m; ++i) { - char op; - int a, b; cin >> op >> a >> b; - - if (op == 'C') { - elem x = query(a - 1, b - 1); - cout << x.h << " " << x.e << " " << x.r << ende; - } else - update(a - 1, b - 1); - } - - cout << ende; - } - - return 0; + return 0; } diff --git a/contests/Cadernaveis/URI1850.cpp b/contests/Cadernaveis/URI1850.cpp index 4bb2e7357d6ab93a60d70186a89cf37a63ece13d..0368b09be29b74809bf27f1f053db74f7f384952 100644 --- a/contests/Cadernaveis/URI1850.cpp +++ b/contests/Cadernaveis/URI1850.cpp @@ -27,57 +27,57 @@ int dy[] = {0, 0, 1, -1}; int cont[110][110][1 << 8]; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - ii arya; - string x; - vector<string> mat; - - for (int i = 0; cin >> x; ++i) { - mat.pb(x); - for (int j = 0; j < x.size(); ++j) - if (x[j] == '@') - arya = {i, j}; - } - - int n = mat.size(), m = mat[0].size(); - - mset(cont, 0); - queue<elem> Q; - Q.push({arya, {0, 0}}); - cont[arya.fi][arya.se][0] = 1; - - while (!Q.empty()) { - elem curr = Q.front(); Q.pop(); - - if (mat[curr.fi.fi][curr.fi.se] == '*') - return cout << curr.se.se << ende, 0; - - for (int i = 0; i < 4; ++i) { - int x = curr.fi.fi + dx[i]; - int y = curr.fi.se + dy[i]; - - if (x >= 0 && x < n && y >= 0 && y < m && - !cont[x][y][curr.se.fi] && mat[x][y] != '#') { - int msk = curr.se.fi; - - if (mat[x][y] >= 'A' && mat[x][y] <= 'G') { - if (msk & (1 << (mat[x][y] - 'A'))) { - cont[x][y][msk] = 1; - Q.push({{x, y}, {msk, curr.se.se + 1}}); - } - } else { - if (mat[x][y] >= 'a' && mat[x][y] <= 'g') - msk |= (1 << (mat[x][y] - 'a')); - - cont[x][y][msk] = 1; - Q.push({{x, y}, {msk, curr.se.se + 1}}); + ios::sync_with_stdio(0); + cin.tie(0); + + ii arya; + string x; + vector<string> mat; + + for (int i = 0; cin >> x; ++i) { + mat.pb(x); + for (int j = 0; j < x.size(); ++j) + if (x[j] == '@') + arya = {i, j}; + } + + int n = mat.size(), m = mat[0].size(); + + mset(cont, 0); + queue<elem> Q; + Q.push({arya, {0, 0}}); + cont[arya.fi][arya.se][0] = 1; + + while (!Q.empty()) { + elem curr = Q.front(); Q.pop(); + + if (mat[curr.fi.fi][curr.fi.se] == '*') + return cout << curr.se.se << ende, 0; + + for (int i = 0; i < 4; ++i) { + int x = curr.fi.fi + dx[i]; + int y = curr.fi.se + dy[i]; + + if (x >= 0 && x < n && y >= 0 && y < m && + !cont[x][y][curr.se.fi] && mat[x][y] != '#') { + int msk = curr.se.fi; + + if (mat[x][y] >= 'A' && mat[x][y] <= 'G') { + if (msk & (1 << (mat[x][y] - 'A'))) { + cont[x][y][msk] = 1; + Q.push({{x, y}, {msk, curr.se.se + 1}}); + } + } else { + if (mat[x][y] >= 'a' && mat[x][y] <= 'g') + msk |= (1 << (mat[x][y] - 'a')); + + cont[x][y][msk] = 1; + Q.push({{x, y}, {msk, curr.se.se + 1}}); + } + } } - } } - } - cout << "--" << ende; - return 0; + cout << "--" << ende; + return 0; } diff --git a/contests/Cadernaveis/URI1852.cpp b/contests/Cadernaveis/URI1852.cpp index 75c35d066c00e6b707b2b0b1af26b983d4a6d9c6..408671a7dcb5bb79c8605c0837d2d2c51ac61cac 100644 --- a/contests/Cadernaveis/URI1852.cpp +++ b/contests/Cadernaveis/URI1852.cpp @@ -22,96 +22,96 @@ using ll = long long; using ii = pair<int,int>; vector<int> gale_shapley(const vector<vector<int>> &pref) { - int n = pref[0].size(); - vector<int> w_part(n, -1); - vector<int> m_part(n, -1); - vector<int> start(n, 0); - - while (true) { - int m; - for (m = 0; m < n; ++m) - if (m_part[m] == -1) - break; - - if (m == n) break; - - for (; start[m] < n && m_part[m] == -1; ++start[m]) { - int w = pref[m][start[m]]; - - if (w_part[w - n] == -1) { - w_part[w - n] = m; - m_part[m] = w; - } else { - int m1 = w_part[w - n]; - bool pref_m = false; - - for (int j = 0; j < n; ++j) - if (pref[w][j] == m) { - pref_m = true; - break; - } else if (pref[w][j] == m1) - break; - - if (pref_m) { - w_part[w - n] = m; - m_part[m] = w; - m_part[m1] = -1; + int n = pref[0].size(); + vector<int> w_part(n, -1); + vector<int> m_part(n, -1); + vector<int> start(n, 0); + + while (true) { + int m; + for (m = 0; m < n; ++m) + if (m_part[m] == -1) + break; + + if (m == n) break; + + for (; start[m] < n && m_part[m] == -1; ++start[m]) { + int w = pref[m][start[m]]; + + if (w_part[w - n] == -1) { + w_part[w - n] = m; + m_part[m] = w; + } else { + int m1 = w_part[w - n]; + bool pref_m = false; + + for (int j = 0; j < n; ++j) + if (pref[w][j] == m) { + pref_m = true; + break; + } else if (pref[w][j] == m1) + break; + + if (pref_m) { + w_part[w - n] = m; + m_part[m] = w; + m_part[m1] = -1; + } + } } - } } - } - return m_part; + return m_part; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n; cin >> n; - vector<vector<int>> pref(2*n, vector<int>(n)); - - int k1 = 0, k2 = n; - map<string,int> M; - vector<string> names(2*n); - for (int i = 0; i < n; ++i) { - string s; cin >> s; - if (M.find(s) == M.end()) { - names[k1] = s; - M[s] = k1++; - } + ios::sync_with_stdio(0); + cin.tie(0); + + int n; cin >> n; + vector<vector<int>> pref(2*n, vector<int>(n)); + + int k1 = 0, k2 = n; + map<string,int> M; + vector<string> names(2*n); + for (int i = 0; i < n; ++i) { + string s; cin >> s; + if (M.find(s) == M.end()) { + names[k1] = s; + M[s] = k1++; + } - for (int j = 0; j < n; ++j) { - string t; cin >> t; - if (M.find(t) == M.end()) { - names[k2] = t; - M[t] = k2++; - } + for (int j = 0; j < n; ++j) { + string t; cin >> t; + if (M.find(t) == M.end()) { + names[k2] = t; + M[t] = k2++; + } - pref[M[s]][j] = M[t]; + pref[M[s]][j] = M[t]; + } } - } - for (int i = 0; i < n; ++i) { - string s; cin >> s; - if (M.find(s) == M.end()) { - names[k2] = s; - M[s] = k2++; - } + for (int i = 0; i < n; ++i) { + string s; cin >> s; + if (M.find(s) == M.end()) { + names[k2] = s; + M[s] = k2++; + } - for (int j = 0; j < n; ++j) { - string t; cin >> t; - if (M.find(t) == M.end()) { - names[k1] = t; - M[t] = k1++; - } + for (int j = 0; j < n; ++j) { + string t; cin >> t; + if (M.find(t) == M.end()) { + names[k1] = t; + M[t] = k1++; + } - pref[M[s]][j] = M[t]; + pref[M[s]][j] = M[t]; + } } - } - vector<int> ans = gale_shapley(pref); - for (int i = 0; i < n; ++i) - cout << names[i] << " " << names[ans[i]] << ende; - return 0; + vector<int> ans = gale_shapley(pref); + for (int i = 0; i < n; ++i) + cout << names[i] << " " << names[ans[i]] << ende; + return 0; } diff --git a/contests/Cadernaveis/URI1860.cpp b/contests/Cadernaveis/URI1860.cpp index a2ce0546846d463fff40c80c5b3a44c2e328fd5b..532c161822da534fd1ea0b3c98ffbc41eaea03cb 100644 --- a/contests/Cadernaveis/URI1860.cpp +++ b/contests/Cadernaveis/URI1860.cpp @@ -23,29 +23,29 @@ using ii = pair<int,int>; using dd = pair<double,double>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - cout << setprecision(2) << fixed; + ios::sync_with_stdio(0); + cin.tie(0); + cout << setprecision(2) << fixed; - int n; - double l = 0.0, r; - cin >> n >> r; + int n; + double l = 0.0, r; + cin >> n >> r; - vector<dd> v(n); - for (auto &i : v) cin >> i.fi >> i.se; + vector<dd> v(n); + for (auto &i : v) cin >> i.fi >> i.se; - double grtl, grtr; - for (int i = 0; i < 100; ++i) { - double lt = (r - l) / 3.0 + l; - double rt = ((r - l) * 2.0) / 3.0 + l; + double grtl, grtr; + for (int i = 0; i < 100; ++i) { + double lt = (r - l) / 3.0 + l; + double rt = ((r - l) * 2.0) / 3.0 + l; - grtl = 0.0; for (auto j : v) grtl = max(grtl, hypot(j.fi - lt, j.se)); - grtr = 0.0; for (auto j : v) grtr = max(grtr, hypot(j.fi - rt, j.se)); + grtl = 0.0; for (auto j : v) grtl = max(grtl, hypot(j.fi - lt, j.se)); + grtr = 0.0; for (auto j : v) grtr = max(grtr, hypot(j.fi - rt, j.se)); - if (grtl > grtr) l = lt; - else r = rt; - } + if (grtl > grtr) l = lt; + else r = rt; + } - cout << l << " " << grtl << ende; - return 0; + cout << l << " " << grtl << ende; + return 0; } diff --git a/contests/Cadernaveis/URI1932_ite.cpp b/contests/Cadernaveis/URI1932_ite.cpp index 4658e6e470b8d00a5e1fcfd2a46f8b101da67b37..be270ebe9009562220df2e883483f68f73bb847c 100644 --- a/contests/Cadernaveis/URI1932_ite.cpp +++ b/contests/Cadernaveis/URI1932_ite.cpp @@ -28,18 +28,18 @@ int v[MAX]; int dp[MAX][2]; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - cin >> n >> c; - for (int i = 0; i < n; ++i) - cin >> v[i]; + cin >> n >> c; + for (int i = 0; i < n; ++i) + cin >> v[i]; - for (int i = n-1; i >= 0; --i) { - dp[i][0] = max(dp[i+1][1] - c - v[i], dp[i+1][0]); - dp[i][1] = max(dp[i+1][0] + v[i], dp[i+1][1]); - } + for (int i = n-1; i >= 0; --i) { + dp[i][0] = max(dp[i+1][1] - c - v[i], dp[i+1][0]); + dp[i][1] = max(dp[i+1][0] + v[i], dp[i+1][1]); + } - cout << dp[0][0] << ende; - return 0; + cout << dp[0][0] << ende; + return 0; } diff --git a/contests/Cadernaveis/URI1932_rec.cpp b/contests/Cadernaveis/URI1932_rec.cpp index ab2e5b0ddf05ada9750b180ea349d828c1e3da1f..de7652b24611f698e6d874280f5ecce8356ae47a 100644 --- a/contests/Cadernaveis/URI1932_rec.cpp +++ b/contests/Cadernaveis/URI1932_rec.cpp @@ -28,31 +28,31 @@ int v[MAX]; int dp[MAX][2]; int solve(int i, bool hold) { - if (i == n) - return 0; - - if (dp[i][hold] != inf) - return dp[i][hold]; - - if (!hold) - return dp[i][hold] = max(solve(i + 1, true) - c - v[i], - solve(i + 1, false)); - else - return dp[i][hold] = max(solve(i + 1, false) + v[i], - solve(i + 1, true)); + if (i == n) + return 0; + + if (dp[i][hold] != inf) + return dp[i][hold]; + + if (!hold) + return dp[i][hold] = max(solve(i + 1, true) - c - v[i], + solve(i + 1, false)); + else + return dp[i][hold] = max(solve(i + 1, false) + v[i], + solve(i + 1, true)); } int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - mset(dp, 0x3f); + mset(dp, 0x3f); - cin >> n >> c; - for (int i = 0; i < n; ++i) - cin >> v[i]; + cin >> n >> c; + for (int i = 0; i < n; ++i) + cin >> v[i]; - cout << solve(0, false) << ende; - return 0; + cout << solve(0, false) << ende; + return 0; } diff --git a/contests/Cadernaveis/URI2305.cpp b/contests/Cadernaveis/URI2305.cpp index b40735d9a76a6a681a7969648b41d718b590973f..cf92fd5b8e3d291b75a66556287c26dd3170265a 100644 --- a/contests/Cadernaveis/URI2305.cpp +++ b/contests/Cadernaveis/URI2305.cpp @@ -22,28 +22,28 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int l, c, m, n; cin >> l >> c >> m >> n; - vector<vector<int>> mat(l, vector<int>(c)); - for (auto &i : mat) for (auto &j : i) cin >> j; - - vector<vector<int>> sum(l+1, vector<int>(c+1, 0)); - for (int i = 1; i <= l; ++i) - for (int j = 1; j <= c; ++j) - if (j == 1) sum[i][j] = mat[i-1][j-1]; - else sum[i][j] = sum[i][j-1] + mat[i-1][j-1]; - - for (int i = 2; i <= l; ++i) - for (int j = 1; j <= c; ++j) - sum[i][j] += sum[i-1][j]; - - int ans = 0; - for (int i = m; i <= l; ++i) - for (int j = n; j <= c; ++j) - ans = max(ans, sum[i][j] - sum[i-m][j] - sum[i][j-n] + sum[i-m][j-n]); - - cout << ans << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int l, c, m, n; cin >> l >> c >> m >> n; + vector<vector<int>> mat(l, vector<int>(c)); + for (auto &i : mat) for (auto &j : i) cin >> j; + + vector<vector<int>> sum(l+1, vector<int>(c+1, 0)); + for (int i = 1; i <= l; ++i) + for (int j = 1; j <= c; ++j) + if (j == 1) sum[i][j] = mat[i-1][j-1]; + else sum[i][j] = sum[i][j-1] + mat[i-1][j-1]; + + for (int i = 2; i <= l; ++i) + for (int j = 1; j <= c; ++j) + sum[i][j] += sum[i-1][j]; + + int ans = 0; + for (int i = m; i <= l; ++i) + for (int j = n; j <= c; ++j) + ans = max(ans, sum[i][j] - sum[i-m][j] - sum[i][j-n] + sum[i-m][j-n]); + + cout << ans << ende; + return 0; } diff --git a/contests/Cadernaveis/UVA10594.cpp b/contests/Cadernaveis/UVA10594.cpp index 265e484de58209edf88da1597b506eda5fe7155c..2892f27aecb6d57c9cdff9cf6165ade7379465ac 100644 --- a/contests/Cadernaveis/UVA10594.cpp +++ b/contests/Cadernaveis/UVA10594.cpp @@ -24,103 +24,103 @@ using ll = long long; using ii = pair<int,int>; struct MinCostMaxFlow { - struct Edge { - int u, v, cap, cost; - }; - - int N; - vector<Edge> edges; - vector<vector<int>> adj; - vector<int> vis, dist, par, ind; - - MinCostMaxFlow(int N) : - N(N), vis(N), dist(N), par(N), ind(N), adj(N) {} - - void add_edge(int u, int v, int cap, int cost) { - adj[u].pb(edges.size()); - edges.pb({ u, v, cap, cost }); - - adj[v].pb(edges.size()); - edges.pb({ v, u, 0, -cost }); - } - - bool spfa(int s, int t) { - fill(all(dist), inf); - dist[s] = 0; - - queue<int> Q; - Q.push(s); - - while (!Q.empty()) { - int u = Q.front(); Q.pop(); - vis[u] = 0; - - for (auto i : adj[u]) { - Edge &e = edges[i]; - int v = e.v; - - if (e.cap > 0 && dist[v] > dist[u] + e.cost) { - dist[v] = dist[u] + e.cost; - par[v] = u; - ind[v] = i; - - if (!vis[v]) { - Q.push(v); - vis[v] = 1; - } - } - } + struct Edge { + int u, v, cap, cost; + }; + + int N; + vector<Edge> edges; + vector<vector<int>> adj; + vector<int> vis, dist, par, ind; + + MinCostMaxFlow(int N) : + N(N), vis(N), dist(N), par(N), ind(N), adj(N) {} + + void add_edge(int u, int v, int cap, int cost) { + adj[u].pb(edges.size()); + edges.pb({ u, v, cap, cost }); + + adj[v].pb(edges.size()); + edges.pb({ v, u, 0, -cost }); } - return dist[t] < inf; - } - - pair<ll,int> run(int s, int t) { - ll mincost = 0; - int maxflow = 0; - - while (spfa(s, t)) { - ll flow = inf; - for (int i = t; i != s; i = par[i]) - flow = min(flow, (ll) edges[ind[i]].cap); - - for (int i = t; i != s; i = par[i]) { - edges[ind[i] ].cap -= flow; - edges[ind[i]^1].cap += flow; - } - - mincost += flow * dist[t]; - maxflow += flow; + bool spfa(int s, int t) { + fill(all(dist), inf); + dist[s] = 0; + + queue<int> Q; + Q.push(s); + + while (!Q.empty()) { + int u = Q.front(); Q.pop(); + vis[u] = 0; + + for (auto i : adj[u]) { + Edge &e = edges[i]; + int v = e.v; + + if (e.cap > 0 && dist[v] > dist[u] + e.cost) { + dist[v] = dist[u] + e.cost; + par[v] = u; + ind[v] = i; + + if (!vis[v]) { + Q.push(v); + vis[v] = 1; + } + } + } + } + + return dist[t] < inf; } - return make_pair(mincost, maxflow); - } + pair<ll,int> run(int s, int t) { + ll mincost = 0; + int maxflow = 0; + + while (spfa(s, t)) { + ll flow = inf; + for (int i = t; i != s; i = par[i]) + flow = min(flow, (ll) edges[ind[i]].cap); + + for (int i = t; i != s; i = par[i]) { + edges[ind[i] ].cap -= flow; + edges[ind[i]^1].cap += flow; + } + + mincost += flow * dist[t]; + maxflow += flow; + } + + return make_pair(mincost, maxflow); + } }; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, m; - while (cin >> n >> m) { - MinCostMaxFlow mcmf(110); - - vector<pair<ii,int>> aux(m); - for (int i = 0; i < m; ++i) - cin >> aux[i].fi.fi >> aux[i].fi.se >> aux[i].se; - - int d, k; cin >> d >> k; - mcmf.add_edge(0, 1, d, 0); - for (int i = 0; i < m; ++i) { - mcmf.add_edge(aux[i].fi.fi, aux[i].fi.se, k, aux[i].se); - mcmf.add_edge(aux[i].fi.se, aux[i].fi.fi, k, aux[i].se); - } + ios::sync_with_stdio(0); + cin.tie(0); + + int n, m; + while (cin >> n >> m) { + MinCostMaxFlow mcmf(110); + + vector<pair<ii,int>> aux(m); + for (int i = 0; i < m; ++i) + cin >> aux[i].fi.fi >> aux[i].fi.se >> aux[i].se; + + int d, k; cin >> d >> k; + mcmf.add_edge(0, 1, d, 0); + for (int i = 0; i < m; ++i) { + mcmf.add_edge(aux[i].fi.fi, aux[i].fi.se, k, aux[i].se); + mcmf.add_edge(aux[i].fi.se, aux[i].fi.fi, k, aux[i].se); + } - pair<ll,int> ans = mcmf.run(0, n); + pair<ll,int> ans = mcmf.run(0, n); - if (ans.se != d) cout << "Impossible." << ende; - else cout << ans.fi << ende; - } + if (ans.se != d) cout << "Impossible." << ende; + else cout << ans.fi << ende; + } - return 0; + return 0; } diff --git a/contests/Cadernaveis/UVA10679_aho.cpp b/contests/Cadernaveis/UVA10679_aho.cpp index 15760390a8aeff86d0c11dbd1efbef3da4e26c8f..badc96af4f64577ae20eb6f65a7db57b2e1645cb 100644 --- a/contests/Cadernaveis/UVA10679_aho.cpp +++ b/contests/Cadernaveis/UVA10679_aho.cpp @@ -1,131 +1,131 @@ /// I Love Strings! (Aho-Corasick) #include <bits/stdc++.h> - + #define MAX 1010101 #define EPS 1e-6 #define MOD 1000000007 #define inf 0x3f3f3f3f #define llinf 0x3f3f3f3f3f3f3f3f - + #define fi first #define se second #define pb push_back #define ende '\n' - + #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() #define mset(x, y) memset(&x, (y), sizeof(x)) - + using namespace std; - + using ll = long long; using ii = pair<int,int>; - + struct AhoCorasick { - struct Node { - int fail, occ, cnt; - vector<int> words; - map<char,int> next; - - Node() : fail(0), occ(-1), cnt(0) {} - int has(char i) { return next.count(i); } - int &operator[](char i) { return next[i]; } - }; - - vector<int> top; - vector<Node> trie; - - AhoCorasick(const vector<string> &v) { - trie.pb(Node()); - build(v); - top = preprocess(); - } - - int insert(const string &s) { - int n = 0; - for (int i = 0; i < s.size(); n = trie[n][s[i]], ++i) - if (!trie[n].has(s[i])) { - trie[n][s[i]] = trie.size(); + struct Node { + int fail, occ, cnt; + vector<int> words; + map<char,int> next; + + Node() : fail(0), occ(-1), cnt(0) {} + int has(char i) { return next.count(i); } + int &operator[](char i) { return next[i]; } + }; + + vector<int> top; + vector<Node> trie; + + AhoCorasick(const vector<string> &v) { trie.pb(Node()); - } - return n; - } - - void build(const vector<string> &v) { - for (int i = 0; i < v.size(); ++i) { - int n = insert(v[i]); - trie[n].words.pb(i); + build(v); + top = preprocess(); + } + + int insert(const string &s) { + int n = 0; + for (int i = 0; i < s.size(); n = trie[n][s[i]], ++i) + if (!trie[n].has(s[i])) { + trie[n][s[i]] = trie.size(); + trie.pb(Node()); + } + return n; } - } - - inline int suffix(int v, char c) { - while (v != 0 && !trie[v].has(c)) v = trie[v].fail; - if (trie[v].has(c)) v = trie[v][c]; - return v; - } - - vector<int> preprocess() { - vector<int> Q = { 0 }; - for (int i = 0; i != Q.size(); ++i) { - int u = Q[i]; - for (auto j : trie[u].next) { - int &v = trie[j.se].fail; - if (u) { - v = suffix(trie[u].fail, j.fi); - trie[j.se].occ = trie[v].words.size() ? v : trie[v].occ; - } else { - v = trie[u].fail; - trie[j.se].occ = -1; + + void build(const vector<string> &v) { + for (int i = 0; i < v.size(); ++i) { + int n = insert(v[i]); + trie[n].words.pb(i); } - Q.pb(j.se); - } } - return Q; - } - - vector<int> match(const string &p) { - int u = 0; - vector<int> ans; - for (auto &i : p) { - u = suffix(u, i); - trie[u].cnt++; + + inline int suffix(int v, char c) { + while (v != 0 && !trie[v].has(c)) v = trie[v].fail; + if (trie[v].has(c)) v = trie[v][c]; + return v; } - for (int i = top.size() - 1; i >= 0; --i) - trie[trie[top[i]].fail].cnt += trie[top[i]].cnt; + vector<int> preprocess() { + vector<int> Q = { 0 }; + for (int i = 0; i != Q.size(); ++i) { + int u = Q[i]; + for (auto j : trie[u].next) { + int &v = trie[j.se].fail; + if (u) { + v = suffix(trie[u].fail, j.fi); + trie[j.se].occ = trie[v].words.size() ? v : trie[v].occ; + } else { + v = trie[u].fail; + trie[j.se].occ = -1; + } + Q.pb(j.se); + } + } + return Q; + } + + vector<int> match(const string &p) { + int u = 0; + vector<int> ans; + for (auto &i : p) { + u = suffix(u, i); + trie[u].cnt++; + } + + for (int i = top.size() - 1; i >= 0; --i) + trie[trie[top[i]].fail].cnt += trie[top[i]].cnt; - for (auto i : trie) - if (i.cnt && i.words.size()) - for (auto j : i.words) ans.pb(j); + for (auto i : trie) + if (i.cnt && i.words.size()) + for (auto j : i.words) ans.pb(j); - sort(all(ans)); - ans.erase(unique(all(ans)), ans.end()); - return ans; - } + sort(all(ans)); + ans.erase(unique(all(ans)), ans.end()); + return ans; + } }; - + int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int t; cin >> t; - while (t--) { - string s; cin >> s; - int n; cin >> n; - vector<string> v(n); - for (auto &i : v) cin >> i; - - AhoCorasick aho(v); - vector<int> ans = aho.match(s); - - for (int i = 0, j = 0; i < n; ++i) { - if (j < ans.size() && ans[j] == i) { - cout << 'y' << ende; ++j; - } else - cout << 'n' << ende; + ios::sync_with_stdio(0); + cin.tie(0); + + int t; cin >> t; + while (t--) { + string s; cin >> s; + int n; cin >> n; + vector<string> v(n); + for (auto &i : v) cin >> i; + + AhoCorasick aho(v); + vector<int> ans = aho.match(s); + + for (int i = 0, j = 0; i < n; ++i) { + if (j < ans.size() && ans[j] == i) { + cout << 'y' << ende; ++j; + } else + cout << 'n' << ende; + } } - } - - return 0; + + return 0; } diff --git a/contests/Cadernaveis/UVA10679_kmp.cpp b/contests/Cadernaveis/UVA10679_kmp.cpp index 5026bcc4c6e2f69c96a69ab856bb852b41bcfe1e..b14e4985942cc8b8f6853de69a63283baff860e2 100644 --- a/contests/Cadernaveis/UVA10679_kmp.cpp +++ b/contests/Cadernaveis/UVA10679_kmp.cpp @@ -22,55 +22,55 @@ using ll = long long; using ii = pair<int,int>; struct KMP { - string patt; - vector<int> table; + string patt; + vector<int> table; - KMP(string patt) : - patt(patt), table(patt.size()+1) - { preprocess(); } + KMP(string patt) : + patt(patt), table(patt.size()+1) + { preprocess(); } - void preprocess() { - fill(all(table), -1); + void preprocess() { + fill(all(table), -1); - for (int i = 0, j = -1; i < patt.size(); ++i) { - while (j >= 0 && patt[i] != patt[j]) - j = table[j]; - table[i + 1] = ++j; + for (int i = 0, j = -1; i < patt.size(); ++i) { + while (j >= 0 && patt[i] != patt[j]) + j = table[j]; + table[i + 1] = ++j; + } } - } - bool search(const string &txt) { - bool found = false; + bool search(const string &txt) { + bool found = false; - for (int i = 0, j = 0; i < txt.size(); ++i) { - while (j >= 0 && txt[i] != patt[j]) - j = table[j]; - j++; + for (int i = 0, j = 0; i < txt.size(); ++i) { + while (j >= 0 && txt[i] != patt[j]) + j = table[j]; + j++; - if (j == patt.size()) { - found = true; - j = table[j]; - } - } + if (j == patt.size()) { + found = true; + j = table[j]; + } + } - return found; - } + return found; + } }; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int t; cin >> t; - for (int cas = 1; cas <= t; ++cas) { - string s; cin >> s; - int q; cin >> q; - for (int i = 0; i < q; ++i) { - string t; cin >> t; - KMP kmp(t); - cout << ((kmp.search(s)) ? "y" : "n") << ende; + ios::sync_with_stdio(0); + cin.tie(0); + + int t; cin >> t; + for (int cas = 1; cas <= t; ++cas) { + string s; cin >> s; + int q; cin >> q; + for (int i = 0; i < q; ++i) { + string t; cin >> t; + KMP kmp(t); + cout << ((kmp.search(s)) ? "y" : "n") << ende; + } } - } - return 0; + return 0; } diff --git a/contests/Cadernaveis/qTREE.cpp b/contests/Cadernaveis/qTREE.cpp index 9a42fd80c9d452cb88e0a7325ba55cac277f7fbe..681c11f3ddc622362a6d86bfc42c347a58398df0 100644 --- a/contests/Cadernaveis/qTREE.cpp +++ b/contests/Cadernaveis/qTREE.cpp @@ -1,203 +1,203 @@ /// Query on a tree #include <bits/stdc++.h> - + #define MAX 10101 #define EPS 1e-6 #define MOD 1000000007 #define inf 0x3f3f3f3f #define llinf 0x3f3f3f3f3f3f3f3f - + #define fi first #define se second #define pb push_back #define ende '\n' - + #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() #define mset(x, y) memset(&x, (y), sizeof(x)) - + using namespace std; - + using ll = long long; using ii = pair<int,int>; - + #define left(x) (x << 1) #define right(x) ((x << 1) + 1) - + int N; - + template <typename T> struct SegmentTree { - using func = function<T(T,T)>; - - func op; - T ident = T(); - vector<T> tree; - - SegmentTree(func op) : - op(op), tree(MAX*4) {} - - void build(const vector<T> &v, - int node = 1, int l = 0, int r = N - 1) - { - if (l > r) - return; - - if (l == r) - tree[node] = v[l]; - else { - int m = (l + r) / 2; - build(v, left(node), l, m); - build(v, right(node), m + 1, r); - tree[node] = op(tree[left(node)], tree[right(node)]); + using func = function<T(T,T)>; + + func op; + T ident = T(); + vector<T> tree; + + SegmentTree(func op) : + op(op), tree(MAX*4) {} + + void build(const vector<T> &v, + int node = 1, int l = 0, int r = N - 1) + { + if (l > r) + return; + + if (l == r) + tree[node] = v[l]; + else { + int m = (l + r) / 2; + build(v, left(node), l, m); + build(v, right(node), m + 1, r); + tree[node] = op(tree[left(node)], tree[right(node)]); + } } - } - - void update(int i, T val, - int node = 1, int l = 0, int r = N - 1) - { - if (l > r || l > i || r < i) - return; - - if (l == r) - tree[node] = val; - else { - int m = (l + r) / 2; - update(i, val, left(node), l, m); - update(i, val, right(node), m + 1, r); - tree[node] = op(tree[left(node)], tree[right(node)]); + + void update(int i, T val, + int node = 1, int l = 0, int r = N - 1) + { + if (l > r || l > i || r < i) + return; + + if (l == r) + tree[node] = val; + else { + int m = (l + r) / 2; + update(i, val, left(node), l, m); + update(i, val, right(node), m + 1, r); + tree[node] = op(tree[left(node)], tree[right(node)]); + } + } + + T query(int i, int j, + int node = 1, int l = 0, int r = N - 1) + { + if (l > r || l > j || r < i) + return ident; + + if (l >= i && r <= j) + return tree[node]; + + int m = (l + r) / 2; + T q1 = query(i, j, left(node), l, m); + T q2 = query(i, j, right(node), m + 1, r); + return op(q1, q2); } - } - - T query(int i, int j, - int node = 1, int l = 0, int r = N - 1) - { - if (l > r || l > j || r < i) - return ident; - - if (l >= i && r <= j) - return tree[node]; - - int m = (l + r) / 2; - T q1 = query(i, j, left(node), l, m); - T q2 = query(i, j, right(node), m + 1, r); - return op(q1, q2); - } }; - + ii edge[MAX]; vector<ii> graph[MAX]; - + template <typename ST> struct HLD { - ST &seg; - int cnum, ptr; - - vector<int> dep, par, val; - vector<int> head, heavy, pos, bot; - - HLD(int n, ST &seg) : - seg(seg), - dep(n, 0), par(n), val(n), - head(n), heavy(n, -1), pos(n), bot(n) - { - cnum = ptr = 0; - - N = n; - dfs(0); - decompose(0); - - for (int i = 0; i < n - 1; ++i) - if (dep[edge[i].fi] > dep[edge[i].se]) - bot[i] = edge[i].fi; - else - bot[i] = edge[i].se; - } - - int dfs(int x, int p = -1) { - int size = 1; - par[x] = p; - - int max_size = 0; - for (auto i : graph[x]) - if (i.fi != p) { - dep[i.fi] = dep[x] + 1; - val[i.fi] = i.se; - int isize = dfs(i.fi, x); - - size += isize; - if (isize > max_size) - max_size = isize, heavy[x] = i.fi; - } - - return size; - } - - void decompose(int x, int h = 0) { - head[x] = h; - seg.update(ptr, val[x]); - pos[x] = ptr++; - - if (heavy[x] != -1) - decompose(heavy[x], h); - - for (auto i : graph[x]) - if (i.fi != par[x] && i.fi != heavy[x]) - decompose(i.fi, i.fi); - } - - int query(int a, int b) { - int ans = seg.ident; - for (; head[a] != head[b]; b = par[head[b]]) { - if (dep[head[a]] > dep[head[b]]) - swap(a, b); - ans = seg.op(ans, seg.query(pos[head[b]], pos[b])); + ST &seg; + int cnum, ptr; + + vector<int> dep, par, val; + vector<int> head, heavy, pos, bot; + + HLD(int n, ST &seg) : + seg(seg), + dep(n, 0), par(n), val(n), + head(n), heavy(n, -1), pos(n), bot(n) + { + cnum = ptr = 0; + + N = n; + dfs(0); + decompose(0); + + for (int i = 0; i < n - 1; ++i) + if (dep[edge[i].fi] > dep[edge[i].se]) + bot[i] = edge[i].fi; + else + bot[i] = edge[i].se; + } + + int dfs(int x, int p = -1) { + int size = 1; + par[x] = p; + + int max_size = 0; + for (auto i : graph[x]) + if (i.fi != p) { + dep[i.fi] = dep[x] + 1; + val[i.fi] = i.se; + int isize = dfs(i.fi, x); + + size += isize; + if (isize > max_size) + max_size = isize, heavy[x] = i.fi; + } + + return size; + } + + void decompose(int x, int h = 0) { + head[x] = h; + seg.update(ptr, val[x]); + pos[x] = ptr++; + + if (heavy[x] != -1) + decompose(heavy[x], h); + + for (auto i : graph[x]) + if (i.fi != par[x] && i.fi != heavy[x]) + decompose(i.fi, i.fi); + } + + int query(int a, int b) { + int ans = seg.ident; + for (; head[a] != head[b]; b = par[head[b]]) { + if (dep[head[a]] > dep[head[b]]) + swap(a, b); + ans = seg.op(ans, seg.query(pos[head[b]], pos[b])); + } + + if (dep[a] > dep[b]) + swap(a, b); + + return seg.op(ans, seg.query(pos[a] + 1, pos[b])); + } + + void update(int i, int val) { + seg.update(pos[bot[i]], val); } - - if (dep[a] > dep[b]) - swap(a, b); - - return seg.op(ans, seg.query(pos[a] + 1, pos[b])); - } - - void update(int i, int val) { - seg.update(pos[bot[i]], val); - } }; - + int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int t; cin >> t; - while (t--) { - int n; cin >> n; - for (int i = 0; i < n; ++i) - graph[i].clear(); - - for (int i = 0; i < n - 1; ++i) { - int a, b, c; cin >> a >> b >> c; - a--, b--; - graph[a].pb(ii(b, c)); - graph[b].pb(ii(a, c)); - edge[i] = ii(a, b); - } - - SegmentTree<int> seg([](int a, int b) { return max(a, b); }); - HLD<SegmentTree<int>> hld(n, seg); - - string op; - while (cin >> op && op != "DONE") { - if (op == "QUERY") { - int a, b; cin >> a >> b; a--, b--; - cout << hld.query(a, b) << ende; - } else { - int idx, w; cin >> idx >> w; idx--; - hld.update(idx, w); - } + ios::sync_with_stdio(0); + cin.tie(0); + + int t; cin >> t; + while (t--) { + int n; cin >> n; + for (int i = 0; i < n; ++i) + graph[i].clear(); + + for (int i = 0; i < n - 1; ++i) { + int a, b, c; cin >> a >> b >> c; + a--, b--; + graph[a].pb(ii(b, c)); + graph[b].pb(ii(a, c)); + edge[i] = ii(a, b); + } + + SegmentTree<int> seg([](int a, int b) { return max(a, b); }); + HLD<SegmentTree<int>> hld(n, seg); + + string op; + while (cin >> op && op != "DONE") { + if (op == "QUERY") { + int a, b; cin >> a >> b; a--, b--; + cout << hld.query(a, b) << ende; + } else { + int idx, w; cin >> idx >> w; idx--; + hld.update(idx, w); + } + } } - } - - return 0; + + return 0; } diff --git a/contests/ICPC_LA14/A.cpp b/contests/ICPC_LA14/A.cpp index 0a3af82c230e6270f137d36eb87f832933038a03..7747832ab48554ea1b1f4a480559f45e8ac93839 100644 --- a/contests/ICPC_LA14/A.cpp +++ b/contests/ICPC_LA14/A.cpp @@ -20,18 +20,18 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - bool poss = true; - vector<int> v(5); - for (auto &i : v) cin >> i; - for (auto &i : v) { - int x; cin >> x; - if (x + i != 1) - poss = false; - } - - cout << (poss ? "Y" : "N") << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + bool poss = true; + vector<int> v(5); + for (auto &i : v) cin >> i; + for (auto &i : v) { + int x; cin >> x; + if (x + i != 1) + poss = false; + } + + cout << (poss ? "Y" : "N") << ende; + return 0; } diff --git a/contests/ICPC_LA14/B.cpp b/contests/ICPC_LA14/B.cpp index 106696f79ccdfd17412a1823986a5d070e5818b1..a9088bf7999d3d6f808d8f709de75a21bb353f59 100644 --- a/contests/ICPC_LA14/B.cpp +++ b/contests/ICPC_LA14/B.cpp @@ -20,28 +20,28 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - ll a, b; cin >> a >> b; - string s; cin >> s; - int n = s.size(); - - int fst = n - 1; - auto update = [&]() { - while (fst >= 0 && s[fst] == 'W') fst--; - }; - - update(); - ll ans = 0; - for (int i = 0; i < n; ++i) { - if (s[i] == 'W' && i < fst) { - ans += min((fst - i) * (a - b), a); - swap(s[fst], s[i]); - update(); + ios::sync_with_stdio(0); + cin.tie(0); + + ll a, b; cin >> a >> b; + string s; cin >> s; + int n = s.size(); + + int fst = n - 1; + auto update = [&]() { + while (fst >= 0 && s[fst] == 'W') fst--; + }; + + update(); + ll ans = 0; + for (int i = 0; i < n; ++i) { + if (s[i] == 'W' && i < fst) { + ans += min((fst - i) * (a - b), a); + swap(s[fst], s[i]); + update(); + } } - } - cout << ans << ende; - return 0; + cout << ans << ende; + return 0; } diff --git a/contests/ICPC_LA14/C.cpp b/contests/ICPC_LA14/C.cpp index 2f74bb04b579c732b5f8cf8324892fb63a52876e..e081b70619bb1a53d2468af538a213052b4f6327 100644 --- a/contests/ICPC_LA14/C.cpp +++ b/contests/ICPC_LA14/C.cpp @@ -20,53 +20,53 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - string s; cin >> s; - int n = s.size(); - bool ne = true; - vector<string> v; - for (int i = 0; i < n; ++i) - if (s[i] >= '0' && s[i] <= '9') { - if (ne) { - v.pb(""); - ne = false; - } - v.back().pb(s[i]); - } else - ne = true; + string s; cin >> s; + int n = s.size(); + bool ne = true; + vector<string> v; + for (int i = 0; i < n; ++i) + if (s[i] >= '0' && s[i] <= '9') { + if (ne) { + v.pb(""); + ne = false; + } + v.back().pb(s[i]); + } else + ne = true; - ll ans = 0; - vector<int> md(3, 0); - for (const auto &i : v) { - int sum = 0; - for (int j = 0; j < i.size(); ++j) { - sum += i[j] - '0'; - md[sum % 3]++; - } + ll ans = 0; + vector<int> md(3, 0); + for (const auto &i : v) { + int sum = 0; + for (int j = 0; j < i.size(); ++j) { + sum += i[j] - '0'; + md[sum % 3]++; + } - for (int j = 0; j < i.size(); ++j) { - ans += md[0]; - if ((i[j] - '0') % 3 == 2) { - md[2]--; - int aux = md[0]; - md[0] = md[2]; - md[2] = md[1]; - md[1] = aux; - } else if ((i[j] - '0') % 3 == 1) { - md[1]--; - int aux = md[1]; - md[1] = md[2]; - md[2] = md[0]; - md[0] = aux; - } else { - md[0]--; - } + for (int j = 0; j < i.size(); ++j) { + ans += md[0]; + if ((i[j] - '0') % 3 == 2) { + md[2]--; + int aux = md[0]; + md[0] = md[2]; + md[2] = md[1]; + md[1] = aux; + } else if ((i[j] - '0') % 3 == 1) { + md[1]--; + int aux = md[1]; + md[1] = md[2]; + md[2] = md[0]; + md[0] = aux; + } else { + md[0]--; + } + } } - } - cout << ans << ende; - return 0; + cout << ans << ende; + return 0; } diff --git a/contests/ICPC_LA14/H.cpp b/contests/ICPC_LA14/H.cpp index 2ec7beb94810da3b7ea7b8c605b46e0e3e53dac9..5f8944056555df7f558bb8eddb9eb8b6b4e2d4f4 100644 --- a/contests/ICPC_LA14/H.cpp +++ b/contests/ICPC_LA14/H.cpp @@ -20,20 +20,20 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n; cin >> n; - vector<int> v(n); - for (auto &i : v) cin >> i; - sort(all(v)); - - int sum1 = 0, sum2 = 0; - for (int i = 0; i < n; i+=2) - sum1 += min(abs(v[i] - v[(i+1)%n]), 24 - abs(v[i] - v[(i+1)%n])); - for (int i = 0; i < n - 1; i+=2) - sum2 += min(abs(v[i] - v[(i-1+n)%n]), 24 - abs(v[i] - v[(i-1+n)%n])); - - cout << min(sum1, sum2) << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int n; cin >> n; + vector<int> v(n); + for (auto &i : v) cin >> i; + sort(all(v)); + + int sum1 = 0, sum2 = 0; + for (int i = 0; i < n; i+=2) + sum1 += min(abs(v[i] - v[(i+1)%n]), 24 - abs(v[i] - v[(i+1)%n])); + for (int i = 0; i < n - 1; i+=2) + sum2 += min(abs(v[i] - v[(i-1+n)%n]), 24 - abs(v[i] - v[(i-1+n)%n])); + + cout << min(sum1, sum2) << ende; + return 0; } diff --git a/contests/ICPC_LA14/I.cpp b/contests/ICPC_LA14/I.cpp index fd8cd6ad022aa271792c927afe9d7b070e7fc665..ece7d031d882507253f90fb6d41e6d676c670e99 100644 --- a/contests/ICPC_LA14/I.cpp +++ b/contests/ICPC_LA14/I.cpp @@ -25,44 +25,44 @@ int tem[MAX]; vector<ii> graph[MAX]; void pre(int x, int p = -1) { - tem[x] = fri[x]; - for (auto i : graph[x]) - if (i.fi != p) { - pre(i.fi, x); - tem[x] += tem[i.fi]; - } + tem[x] = fri[x]; + for (auto i : graph[x]) + if (i.fi != p) { + pre(i.fi, x); + tem[x] += tem[i.fi]; + } } ii solve(int x, int p = -1) { - ii ans{0, 0}; - for (auto i : graph[x]) - if (i.fi != p && tem[i.fi]) { - ii a = solve(i.fi, x); - ans.fi = max(ans.fi, a.fi + i.se); - ans.se += a.se + i.se; - } + ii ans{0, 0}; + for (auto i : graph[x]) + if (i.fi != p && tem[i.fi]) { + ii a = solve(i.fi, x); + ans.fi = max(ans.fi, a.fi + i.se); + ans.se += a.se + i.se; + } - return ans; + return ans; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int n, f; cin >> n >> f; - for (int i = 0; i < n - 1; ++i) { - int a, b, c; cin >> a >> b >> c; a--, b--; - graph[a].pb(ii(b, c)); - graph[b].pb(ii(a, c)); - } + int n, f; cin >> n >> f; + for (int i = 0; i < n - 1; ++i) { + int a, b, c; cin >> a >> b >> c; a--, b--; + graph[a].pb(ii(b, c)); + graph[b].pb(ii(a, c)); + } - for (int i = 0; i < f; ++i) { - int x; cin >> x; x--; - fri[x] = 1; - } + for (int i = 0; i < f; ++i) { + int x; cin >> x; x--; + fri[x] = 1; + } - pre(0); - ii ans = solve(0); - cout << ans.se - ans.fi << ende; - return 0; + pre(0); + ii ans = solve(0); + cout << ans.se - ans.fi << ende; + return 0; } diff --git a/contests/ICPC_LA16/A.cpp b/contests/ICPC_LA16/A.cpp index 43060751f0d86bc96070babd86b45635f97cbf33..218e45d7355b684608340867d26c5b0e78a5be8d 100644 --- a/contests/ICPC_LA16/A.cpp +++ b/contests/ICPC_LA16/A.cpp @@ -22,13 +22,13 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - vector<int> v(4); - for (auto &i : v) cin >> i; - sort(all(v)); + vector<int> v(4); + for (auto &i : v) cin >> i; + sort(all(v)); - cout << abs((v[0] + v[3]) - (v[1] + v[2])) << ende; - return 0; + cout << abs((v[0] + v[3]) - (v[1] + v[2])) << ende; + return 0; } diff --git a/contests/ICPC_LA16/B.cpp b/contests/ICPC_LA16/B.cpp index d625d434f299c26c4daf29866dfad93e3d447e31..1e76ab2f878ea5ad3c5214c5c9da045784a70f27 100644 --- a/contests/ICPC_LA16/B.cpp +++ b/contests/ICPC_LA16/B.cpp @@ -25,50 +25,50 @@ using ii = pair<int,int>; set<int> graph[MAX]; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, m, a, b; cin >> n >> m >> a >> b; - for (int i = 0; i < m; ++i) { - int x, y; cin >> x >> y; - graph[x].insert(y); - graph[y].insert(x); - } - - set<ii> S; - for (int i = 1; i <= n; ++i) - S.insert(ii(graph[i].size(), i)); - - bool ended = false; - while (!ended) { - ended = true; - while (S.size() && S.begin()->fi < a) { - ii u = *(S.begin()); S.erase(S.begin()); - - for (auto i : graph[u.se]) { - S.erase(ii(graph[i].size(), i)); - graph[i].erase(u.se); - S.insert(ii(graph[i].size(), i)); - } - - graph[u.se].clear(); - ended = false; + ios::sync_with_stdio(0); + cin.tie(0); + + int n, m, a, b; cin >> n >> m >> a >> b; + for (int i = 0; i < m; ++i) { + int x, y; cin >> x >> y; + graph[x].insert(y); + graph[y].insert(x); } - while (S.size() && S.size() - prev(S.end())->fi - 1 < b) { - ii u = *(prev(S.end())); S.erase(prev(S.end())); - - for (auto i : graph[u.se]) { - S.erase(ii(graph[i].size(), i)); - graph[i].erase(u.se); + set<ii> S; + for (int i = 1; i <= n; ++i) S.insert(ii(graph[i].size(), i)); - } - graph[u.se].clear(); - ended = false; + bool ended = false; + while (!ended) { + ended = true; + while (S.size() && S.begin()->fi < a) { + ii u = *(S.begin()); S.erase(S.begin()); + + for (auto i : graph[u.se]) { + S.erase(ii(graph[i].size(), i)); + graph[i].erase(u.se); + S.insert(ii(graph[i].size(), i)); + } + + graph[u.se].clear(); + ended = false; + } + + while (S.size() && S.size() - prev(S.end())->fi - 1 < b) { + ii u = *(prev(S.end())); S.erase(prev(S.end())); + + for (auto i : graph[u.se]) { + S.erase(ii(graph[i].size(), i)); + graph[i].erase(u.se); + S.insert(ii(graph[i].size(), i)); + } + + graph[u.se].clear(); + ended = false; + } } - } - cout << S.size() << ende; - return 0; + cout << S.size() << ende; + return 0; } diff --git a/contests/ICPC_LA16/D.cpp b/contests/ICPC_LA16/D.cpp index f9bf5df5a11e9f63403e3d121c89acdab7a5e2f8..fc8b4de533a706f2164a524c79260cf829d1265d 100644 --- a/contests/ICPC_LA16/D.cpp +++ b/contests/ICPC_LA16/D.cpp @@ -25,31 +25,31 @@ using ii = pair<int,int>; using dd = pair<double,double>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - cout << setprecision(3) << fixed; - - int n; cin >> n; - vector<int> v(n); - for (auto &i : v) cin >> i; - sort(all(v)); - - vector<int> u(n); - int a = 0, b = n - 1; - for (int i = 0; i < n; ++i) { - if (i % 2) u[b--] = v[i]; - else u[a++] = v[i]; - } - - vector<dd> points(n); - for (int i = 0; i < n; ++i) { - points[i].fi = u[i] * cos(to_rad((360.0 / n) * (i + 1))); - points[i].se = u[i] * sin(to_rad((360.0 / n) * (i + 1))); - } - - double sum = 0.0; - for (int i = 0; i < n; ++i) - sum += points[i].fi * points[(i+1) % n].se - points[i].se * points[(i+1)%n].fi; - cout << sum / 2.0 << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + cout << setprecision(3) << fixed; + + int n; cin >> n; + vector<int> v(n); + for (auto &i : v) cin >> i; + sort(all(v)); + + vector<int> u(n); + int a = 0, b = n - 1; + for (int i = 0; i < n; ++i) { + if (i % 2) u[b--] = v[i]; + else u[a++] = v[i]; + } + + vector<dd> points(n); + for (int i = 0; i < n; ++i) { + points[i].fi = u[i] * cos(to_rad((360.0 / n) * (i + 1))); + points[i].se = u[i] * sin(to_rad((360.0 / n) * (i + 1))); + } + + double sum = 0.0; + for (int i = 0; i < n; ++i) + sum += points[i].fi * points[(i+1) % n].se - points[i].se * points[(i+1)%n].fi; + cout << sum / 2.0 << ende; + return 0; } diff --git a/contests/ICPC_LA16/F.cpp b/contests/ICPC_LA16/F.cpp index b1a5f4af2aa70f84796151d392c7fbb950d63287..1d31e61312b2084d65ef44c2386c8ac9fabf73d3 100644 --- a/contests/ICPC_LA16/F.cpp +++ b/contests/ICPC_LA16/F.cpp @@ -22,18 +22,18 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, c, s; cin >> n >> c >> s; s--; - int curr = 0, ans = curr == s; - for (int i = 0; i < c; ++i) { - int x; cin >> x; - curr = ((curr + x) + n) % n; - if (curr == s) - ans++; - } - - cout << ans << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int n, c, s; cin >> n >> c >> s; s--; + int curr = 0, ans = curr == s; + for (int i = 0; i < c; ++i) { + int x; cin >> x; + curr = ((curr + x) + n) % n; + if (curr == s) + ans++; + } + + cout << ans << ende; + return 0; } diff --git a/contests/ICPC_LA16/G.cpp b/contests/ICPC_LA16/G.cpp index 3be349181f5ce1cbee35a70124850cdaaa8d0f03..fe9d676f188951a5e626c512fb38c9d3f8c7a7a5 100644 --- a/contests/ICPC_LA16/G.cpp +++ b/contests/ICPC_LA16/G.cpp @@ -22,66 +22,66 @@ using ll = long long; using ii = pair<int,int>; struct KMP { - vector<int> patt; - vector<int> table; + vector<int> patt; + vector<int> table; - KMP(vector<int> patt) : - patt(patt), table(patt.size()+1) - { preprocess(); } + KMP(vector<int> patt) : + patt(patt), table(patt.size()+1) + { preprocess(); } - void preprocess() { - fill(all(table), -1); + void preprocess() { + fill(all(table), -1); - for (int i = 0, j = -1; i < patt.size(); ++i) { - while (j >= 0 && patt[i] != patt[j] && (patt[j] || patt[i] <= j)) - j = table[j]; - table[i + 1] = ++j; - } - } - - int search(const vector<int> &txt) { - int ans = 0; - for (int i = 0, j = 0; i < txt.size(); ++i) { - while (j >= 0 && txt[i] != patt[j] && (patt[j] || txt[i] <= j)) - j = table[j]; - ++j; - if (j == patt.size()) { - ans++; - j = table[j]; - } + for (int i = 0, j = -1; i < patt.size(); ++i) { + while (j >= 0 && patt[i] != patt[j] && (patt[j] || patt[i] <= j)) + j = table[j]; + table[i + 1] = ++j; + } } - return ans; - } + int search(const vector<int> &txt) { + int ans = 0; + for (int i = 0, j = 0; i < txt.size(); ++i) { + while (j >= 0 && txt[i] != patt[j] && (patt[j] || txt[i] <= j)) + j = table[j]; + ++j; + if (j == patt.size()) { + ans++; + j = table[j]; + } + } + + return ans; + } }; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - string s; cin >> s; - int n; cin >> n; - vector<int> v(n); - for (auto &i : v) { - cin >> i; --i; - } - - vector<int> last(30, -1); - vector<int> A(s.size()), B(n); - for (int i = 0; i < s.size(); ++i) { - if (last[s[i] - 'a'] == -1) A[i] = 0; - else A[i] = i - last[s[i] - 'a']; - last[s[i] - 'a'] = i; - } - - fill(all(last), -1); - for (int i = 0; i < v.size(); ++i) { - if (last[v[i]] == -1) B[i] = 0; - else B[i] = i - last[v[i]]; - last[v[i]] = i; - } - - KMP kmp(B); - cout << kmp.search(A) << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + string s; cin >> s; + int n; cin >> n; + vector<int> v(n); + for (auto &i : v) { + cin >> i; --i; + } + + vector<int> last(30, -1); + vector<int> A(s.size()), B(n); + for (int i = 0; i < s.size(); ++i) { + if (last[s[i] - 'a'] == -1) A[i] = 0; + else A[i] = i - last[s[i] - 'a']; + last[s[i] - 'a'] = i; + } + + fill(all(last), -1); + for (int i = 0; i < v.size(); ++i) { + if (last[v[i]] == -1) B[i] = 0; + else B[i] = i - last[v[i]]; + last[v[i]] = i; + } + + KMP kmp(B); + cout << kmp.search(A) << ende; + return 0; } diff --git a/contests/ICPC_LA16/H.cpp b/contests/ICPC_LA16/H.cpp index e192a2f725e74370c5d69ce2ba393b1ed67e90e0..40731a420ed25de4ff75ef2e72ff774bb4b1f67f 100644 --- a/contests/ICPC_LA16/H.cpp +++ b/contests/ICPC_LA16/H.cpp @@ -22,22 +22,22 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, k; cin >> n >> k; - - int ans = 0; - multiset<int> S; - for (int i = 0; i < n; ++i) { - int x; cin >> x; - ans += x; - S.insert(x); - while (S.size() > (i + 1) / (k + 1)) - S.erase(S.begin()); - } - - for (auto i : S) ans -= i; - cout << ans << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int n, k; cin >> n >> k; + + int ans = 0; + multiset<int> S; + for (int i = 0; i < n; ++i) { + int x; cin >> x; + ans += x; + S.insert(x); + while (S.size() > (i + 1) / (k + 1)) + S.erase(S.begin()); + } + + for (auto i : S) ans -= i; + cout << ans << ende; + return 0; } diff --git a/contests/ICPC_LA16/J.cpp b/contests/ICPC_LA16/J.cpp index 60a757391b01a541c6f2ee56507578a04b349a49..d4760572802657e9140668597aa5499ec11ed8be 100644 --- a/contests/ICPC_LA16/J.cpp +++ b/contests/ICPC_LA16/J.cpp @@ -22,23 +22,23 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n; cin >> n; - if (n == 2) return cout << 2 << ende, 0; - for (int i = n; i >= 0; --i) { - if (i % 2 == 0) continue; - bool done = true; - for (int j = 3; j * j <= n; j += 2) - if (i % j == 0) { - done = false; - break; - } - - if (done) - return cout << i << ende, 0; - } - - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int n; cin >> n; + if (n == 2) return cout << 2 << ende, 0; + for (int i = n; i >= 0; --i) { + if (i % 2 == 0) continue; + bool done = true; + for (int j = 3; j * j <= n; j += 2) + if (i % j == 0) { + done = false; + break; + } + + if (done) + return cout << i << ende, 0; + } + + return 0; } diff --git a/contests/ICPC_LA16/K.cpp b/contests/ICPC_LA16/K.cpp index 6e46d2344a3d411df4fef7317ef6a410844b0883..39d648e33ce066813f994f879aef5bb5f36842ce 100644 --- a/contests/ICPC_LA16/K.cpp +++ b/contests/ICPC_LA16/K.cpp @@ -22,117 +22,117 @@ using ll = long long; using ii = pair<int,int>; struct Dinic { - struct Edge { int u, f, c, r; }; + struct Edge { int u, f, c, r; }; - int N; - vector<int> depth, start; - vector<vector<Edge>> graph; + int N; + vector<int> depth, start; + vector<vector<Edge>> graph; - Dinic(int N) : - N(N), depth(N), start(N), graph(N) {} + Dinic(int N) : + N(N), depth(N), start(N), graph(N) {} - void add_edge(int s, int t, int c) { - Edge forw = { t, 0, c, (int) graph[t].size() }; - Edge back = { s, 0, 0, (int) graph[s].size() }; + void add_edge(int s, int t, int c) { + Edge forw = { t, 0, c, (int) graph[t].size() }; + Edge back = { s, 0, 0, (int) graph[s].size() }; - graph[s].pb(forw); - graph[t].pb(back); - } + graph[s].pb(forw); + graph[t].pb(back); + } - bool bfs(int s, int t) { - queue<int> Q; - Q.push(s); + bool bfs(int s, int t) { + queue<int> Q; + Q.push(s); - fill(all(depth), -1); - depth[s] = 0; + fill(all(depth), -1); + depth[s] = 0; - while (!Q.empty()) { - int v = Q.front(); Q.pop(); + while (!Q.empty()) { + int v = Q.front(); Q.pop(); - for (auto i : graph[v]) - if (depth[i.u] == -1 && i.f < i.c) { - depth[i.u] = depth[v] + 1; - Q.push(i.u); + for (auto i : graph[v]) + if (depth[i.u] == -1 && i.f < i.c) { + depth[i.u] = depth[v] + 1; + Q.push(i.u); + } } - } - return depth[t] != -1; - } + return depth[t] != -1; + } - int dfs(int s, int t, int f) { - if (s == t) - return f; + int dfs(int s, int t, int f) { + if (s == t) + return f; - for ( ; start[s] < graph[s].size(); ++start[s]) { - Edge &e = graph[s][start[s]]; + for ( ; start[s] < graph[s].size(); ++start[s]) { + Edge &e = graph[s][start[s]]; - if (depth[e.u] == depth[s] + 1 && e.f < e.c) { - int min_f = dfs(e.u, t, min(f, e.c - e.f)); + if (depth[e.u] == depth[s] + 1 && e.f < e.c) { + int min_f = dfs(e.u, t, min(f, e.c - e.f)); - if (min_f > 0) { - e.f += min_f; - graph[e.u][e.r].f -= min_f; - return min_f; + if (min_f > 0) { + e.f += min_f; + graph[e.u][e.r].f -= min_f; + return min_f; + } + } } - } + + return 0; } - return 0; - } + int run(int s, int t) { + int ans = 0; + while (bfs(s, t)) { + fill(all(start), 0); - int run(int s, int t) { - int ans = 0; - while (bfs(s, t)) { - fill(all(start), 0); + while (int flow = dfs(s, t, inf)) + ans += flow; + } - while (int flow = dfs(s, t, inf)) - ans += flow; + return ans; } - - return ans; - } }; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n; cin >> n; - vector<ii> v(n+1); - for (int i = 1; i <= n; ++i) - cin >> v[i].fi >> v[i].se; - - int ans = 0; - for (int i = 1; i <= n; ++i) { - int votes = 0, pass = 0; - int s = 0, t = 2*n + 1; - Dinic dinic(t + 1); - - for (int j = 1; j <= n; ++j) { - if (i == j) - continue; - - if (v[j].fi == i || v[j].se == i) { - votes++; - continue; - } - - dinic.add_edge(s, j, 1); - dinic.add_edge(j, v[j].fi + n, 1); - dinic.add_edge(j, v[j].se + n, 1); - pass++; - } + ios::sync_with_stdio(0); + cin.tie(0); + + int n; cin >> n; + vector<ii> v(n+1); + for (int i = 1; i <= n; ++i) + cin >> v[i].fi >> v[i].se; - for (int j = 1; j <= n; ++j) - if (v[i].fi == j || v[i].se == j) - dinic.add_edge(j + n, t, votes - 2); - else - dinic.add_edge(j + n, t, votes - 1); + int ans = 0; + for (int i = 1; i <= n; ++i) { + int votes = 0, pass = 0; + int s = 0, t = 2*n + 1; + Dinic dinic(t + 1); + + for (int j = 1; j <= n; ++j) { + if (i == j) + continue; + + if (v[j].fi == i || v[j].se == i) { + votes++; + continue; + } + + dinic.add_edge(s, j, 1); + dinic.add_edge(j, v[j].fi + n, 1); + dinic.add_edge(j, v[j].se + n, 1); + pass++; + } - if (dinic.run(s, t) < pass) - ans++; - } + for (int j = 1; j <= n; ++j) + if (v[i].fi == j || v[i].se == j) + dinic.add_edge(j + n, t, votes - 2); + else + dinic.add_edge(j + n, t, votes - 1); - cout << ans << ende; - return 0; + if (dinic.run(s, t) < pass) + ans++; + } + + cout << ans << ende; + return 0; } diff --git a/contests/ICPC_LA17/B.cpp b/contests/ICPC_LA17/B.cpp index b5a56d7070e794e4d3321276616e101fd3827d05..cb5b6ba167d37139830206bcae14fad95aeb24ea 100644 --- a/contests/ICPC_LA17/B.cpp +++ b/contests/ICPC_LA17/B.cpp @@ -22,51 +22,51 @@ using ll = long long; using ii = pair<int,int>; bool is_vowel(char x) { - return x == 'a' || x == 'e' || x == 'i' || x == 'o' || x == 'u'; + return x == 'a' || x == 'e' || x == 'i' || x == 'o' || x == 'u'; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int num_vow = 0; - string s; cin >> s; - for (auto i : s) num_vow += is_vowel(i); - if (num_vow && !is_vowel(s[0])) - return cout << 0 << ende, 0; - if (num_vow == 0) - return cout << 1 << ende, 0; + int num_vow = 0; + string s; cin >> s; + for (auto i : s) num_vow += is_vowel(i); + if (num_vow && !is_vowel(s[0])) + return cout << 0 << ende, 0; + if (num_vow == 0) + return cout << 1 << ende, 0; - int i = 0, n = s.size() - 1; - bool inverted = false; + int i = 0, n = s.size() - 1; + bool inverted = false; - auto invert = [&]() { - swap(i, n); - inverted = !inverted; - }; + auto invert = [&]() { + swap(i, n); + inverted = !inverted; + }; - auto trim_tail = [&]() { - if (inverted) n++; - else n--; - }; + auto trim_tail = [&]() { + if (inverted) n++; + else n--; + }; - int ans = 0; - while (abs(n - i)) { - if (is_vowel(s[i]) && is_vowel(s[n])) { - invert(); - trim_tail(); - num_vow--; - } else if (!is_vowel(s[i]) && is_vowel(s[n])) { - break; - } else if (is_vowel(s[i]) && !is_vowel(s[n])) { - if (num_vow == 1) ans++; - trim_tail(); - } else if (!is_vowel(s[i]) && !is_vowel(s[n])) { - trim_tail(); + int ans = 0; + while (abs(n - i)) { + if (is_vowel(s[i]) && is_vowel(s[n])) { + invert(); + trim_tail(); + num_vow--; + } else if (!is_vowel(s[i]) && is_vowel(s[n])) { + break; + } else if (is_vowel(s[i]) && !is_vowel(s[n])) { + if (num_vow == 1) ans++; + trim_tail(); + } else if (!is_vowel(s[i]) && !is_vowel(s[n])) { + trim_tail(); + } } - } - if (i == n && is_vowel(s[i])) ans++; - cout << ans << ende; - return 0; + if (i == n && is_vowel(s[i])) ans++; + cout << ans << ende; + return 0; } diff --git a/contests/ICPC_LA17/C.cpp b/contests/ICPC_LA17/C.cpp index 25d19868836fe8fecb6467f3f07c5472f9be06d9..4da5b2313224fc15d18e534d27e5bbcebb56524b 100644 --- a/contests/ICPC_LA17/C.cpp +++ b/contests/ICPC_LA17/C.cpp @@ -22,40 +22,40 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, k; cin >> k >> n; - vector<int> cnt(k + 1); - for (int i = 0; i < n; ++i) { - int x; cin >> x; cnt[x]++; - } - - set<int> S; - vector<int> v; - - for (int i = 1; i <= k; ++i) S.insert(cnt[i]); - for (auto i : S) v.pb(i); - - auto find_cnt = [&](int x) { - for (int i = 1; i <= k; ++i) - if (cnt[i] == x) - return i; - - assert(false); - }; - - int flo = n / k; - int cei = (n - 1) / k + 1; - - if (n % k == 0 && (v.size() == 3 && v[0] == v[1] - 1 && v[1] == v[2] - 1)) - cout << "-" << find_cnt(v[2]) << " " << "+" << find_cnt(v[0]) << ende; - else if (flo * k + 1 == n && (v.size() == 2 && v[0] == v[1] - 1)) - cout << "-" << find_cnt(v[1]) << ende; - else if (cei * k - 1 == n && (v.size() == 2 && v[0] == v[1] - 1)) - cout << "+" << find_cnt(v[0]) << ende; - else - cout << "*" << ende; - - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int n, k; cin >> k >> n; + vector<int> cnt(k + 1); + for (int i = 0; i < n; ++i) { + int x; cin >> x; cnt[x]++; + } + + set<int> S; + vector<int> v; + + for (int i = 1; i <= k; ++i) S.insert(cnt[i]); + for (auto i : S) v.pb(i); + + auto find_cnt = [&](int x) { + for (int i = 1; i <= k; ++i) + if (cnt[i] == x) + return i; + + assert(false); + }; + + int flo = n / k; + int cei = (n - 1) / k + 1; + + if (n % k == 0 && (v.size() == 3 && v[0] == v[1] - 1 && v[1] == v[2] - 1)) + cout << "-" << find_cnt(v[2]) << " " << "+" << find_cnt(v[0]) << ende; + else if (flo * k + 1 == n && (v.size() == 2 && v[0] == v[1] - 1)) + cout << "-" << find_cnt(v[1]) << ende; + else if (cei * k - 1 == n && (v.size() == 2 && v[0] == v[1] - 1)) + cout << "+" << find_cnt(v[0]) << ende; + else + cout << "*" << ende; + + return 0; } diff --git a/contests/ICPC_LA17/D.cpp b/contests/ICPC_LA17/D.cpp index dde13c8de2a959a35f06cdc1108f6c6245f59a50..e74ecd3aeef86bffa387eba4ca65195296fd00a0 100644 --- a/contests/ICPC_LA17/D.cpp +++ b/contests/ICPC_LA17/D.cpp @@ -23,51 +23,51 @@ using ii = pair<int,int>; using iii = pair<ii,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - ll l, c, n; cin >> l >> c >> n; - set<iii> S; - S.insert(iii(ii(0, l - 1), 1)); - vector<ll> num(c+1, 0); - num[1] = l; - - for (int i = 0; i < n; ++i) { - ll p, x, a, b; cin >> p >> x >> a >> b; - int m1 = (a + num[p] * num[p]) % l; - int m2 = (a + (num[p] + b) * (num[p] + b)) % l; - - if (m1 > m2) swap(m1, m2); - auto curr = prev(S.lower_bound(iii(ii(m1 + 1, -inf), -inf))); - - vector<iii> ins, del; - ins.pb(iii(ii(m1, m2), x)); - for ( ; curr != S.end() && curr->fi.fi <= m2; ++curr) { - num[curr->se] -= curr->fi.se - curr->fi.fi + 1; - - // m1 intersects with section - if (m1 >= curr->fi.fi && m1 <= curr->fi.se) { - ins.pb(iii(ii(curr->fi.fi, m1 - 1), curr->se)); - num[curr->se] += (m1 - 1) - curr->fi.fi + 1; - } - - // m2 intersects with section - if (m2 >= curr->fi.fi && m2 <= curr->fi.se) { - ins.pb(iii(ii(m2 + 1, curr->fi.se), curr->se)); - num[curr->se] += curr->fi.se - (m2 + 1) + 1; - } - - num[x] += min(m2, curr->fi.se) - max(m1, curr->fi.fi) + 1; - del.pb(*curr); - } + ios::sync_with_stdio(0); + cin.tie(0); + + ll l, c, n; cin >> l >> c >> n; + set<iii> S; + S.insert(iii(ii(0, l - 1), 1)); + vector<ll> num(c+1, 0); + num[1] = l; + + for (int i = 0; i < n; ++i) { + ll p, x, a, b; cin >> p >> x >> a >> b; + int m1 = (a + num[p] * num[p]) % l; + int m2 = (a + (num[p] + b) * (num[p] + b)) % l; + + if (m1 > m2) swap(m1, m2); + auto curr = prev(S.lower_bound(iii(ii(m1 + 1, -inf), -inf))); + + vector<iii> ins, del; + ins.pb(iii(ii(m1, m2), x)); + for ( ; curr != S.end() && curr->fi.fi <= m2; ++curr) { + num[curr->se] -= curr->fi.se - curr->fi.fi + 1; - for (auto j : del) S.erase(j); - for (auto j : ins) S.insert(j); - } + // m1 intersects with section + if (m1 >= curr->fi.fi && m1 <= curr->fi.se) { + ins.pb(iii(ii(curr->fi.fi, m1 - 1), curr->se)); + num[curr->se] += (m1 - 1) - curr->fi.fi + 1; + } + + // m2 intersects with section + if (m2 >= curr->fi.fi && m2 <= curr->fi.se) { + ins.pb(iii(ii(m2 + 1, curr->fi.se), curr->se)); + num[curr->se] += curr->fi.se - (m2 + 1) + 1; + } + + num[x] += min(m2, curr->fi.se) - max(m1, curr->fi.fi) + 1; + del.pb(*curr); + } + + for (auto j : del) S.erase(j); + for (auto j : ins) S.insert(j); + } - ll ans = 0; - for (int i = 1; i <= c; ++i) - ans = max(ans, num[i]); - cout << ans << ende; - return 0; + ll ans = 0; + for (int i = 1; i <= c; ++i) + ans = max(ans, num[i]); + cout << ans << ende; + return 0; } diff --git a/contests/ICPC_LA17/E.cpp b/contests/ICPC_LA17/E.cpp index 302e3bc37fa57bd71233ac08e41487dab9c188df..71aa7cf311ff1b1effa8a39a07c46ff5ab69eed2 100644 --- a/contests/ICPC_LA17/E.cpp +++ b/contests/ICPC_LA17/E.cpp @@ -27,33 +27,33 @@ string s; int dp[MAX][MAX]; bool solve(int i, int r) { - if (i == s.size()) - return (r % n == 0); - - if (dp[i][r] != -1) - return dp[i][r]; - - if (s[i] == '?') { - for (int j = (i == 0); j <= 9; ++j) - if (solve(i + 1, (r * 10 + j) % n)) { - s[i] = j + '0'; - return dp[i][r] = true; - } - } else { - if (solve(i + 1, (r * 10 + (s[i] - '0')) % n)) - return dp[i][r] = true; - } - - return dp[i][r] = false; + if (i == s.size()) + return (r % n == 0); + + if (dp[i][r] != -1) + return dp[i][r]; + + if (s[i] == '?') { + for (int j = (i == 0); j <= 9; ++j) + if (solve(i + 1, (r * 10 + j) % n)) { + s[i] = j + '0'; + return dp[i][r] = true; + } + } else { + if (solve(i + 1, (r * 10 + (s[i] - '0')) % n)) + return dp[i][r] = true; + } + + return dp[i][r] = false; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - cin >> s >> n; - mset(dp, -1); + cin >> s >> n; + mset(dp, -1); - cout << (!solve(0, 0) ? "*" : s) << ende; - return 0; + cout << (!solve(0, 0) ? "*" : s) << ende; + return 0; } diff --git a/contests/ICPC_LA17/F.cpp b/contests/ICPC_LA17/F.cpp index 5842ed3fe4d10fb318992965c3cd74c7c91d9fb2..4123a9d97b5128b788e09fb725715e561f4548a4 100644 --- a/contests/ICPC_LA17/F.cpp +++ b/contests/ICPC_LA17/F.cpp @@ -24,82 +24,82 @@ using ii = pair<ll,ll>; using iii = pair<ii,ll>; struct BIT { - int N; - vector<ll> tree; - - BIT(int N) : - N(N), tree(N) - {} - - void init() { - fill(all(tree), 0LL); - } - - ll query(int idx) { - ll sum = 0LL; - for (; idx > 0; idx -= (idx & -idx)) - sum = max(sum, tree[idx]); - return sum; - } - - void update(int idx, ll val) { - for (; idx < N; idx += (idx & -idx)) - tree[idx] = max(tree[idx], val); - } + int N; + vector<ll> tree; + + BIT(int N) : + N(N), tree(N) + {} + + void init() { + fill(all(tree), 0LL); + } + + ll query(int idx) { + ll sum = 0LL; + for (; idx > 0; idx -= (idx & -idx)) + sum = max(sum, tree[idx]); + return sum; + } + + void update(int idx, ll val) { + for (; idx < N; idx += (idx & -idx)) + tree[idx] = max(tree[idx], val); + } }; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - BIT bit(MAX); - bit.init(); - - map<ii,ll> M; - int n; cin >> n; - for (int i = 0; i < n; ++i) { - ll a, b, c; cin >> a >> b >> c; - M[ii(a, b)] += c; - } - - vector<iii> v; - for (auto i : M) - v.pb(iii(ii(i.fi.fi, i.fi.se), i.se)); - n = v.size(); - - sort(all(v), [](const iii &a, const iii &b) { - if (a.fi.fi != b.fi.fi) - return a.fi.fi < b.fi.fi; - else if (a.fi.se != b.fi.se) - return a.fi.se > b.fi.se; - return a.se > b.se; - }); - - set<ll> S; - map<ll,ll> compress; - for (auto i : v) - S.insert(i.fi.se); - - ll k = 1LL; - for (auto i : S) - compress[i] = k++; - for (auto &i : v) - i.fi.se = compress[i.fi.se]; - - ll ans = 0, last = v[0].fi.fi; - for (int i = 0; ; ) { - for (; i < n && v[i].fi.fi == last; ++i) { - ll bst = max(bit.query(v[i].fi.se - 1) + v[i].se, - bit.query(v[i].fi.se)); - - bit.update(v[i].fi.se, bst); - ans = max(ans, bst); + ios::sync_with_stdio(0); + cin.tie(0); + + BIT bit(MAX); + bit.init(); + + map<ii,ll> M; + int n; cin >> n; + for (int i = 0; i < n; ++i) { + ll a, b, c; cin >> a >> b >> c; + M[ii(a, b)] += c; } - if (i >= n) break; - last = v[i].fi.fi; - } + vector<iii> v; + for (auto i : M) + v.pb(iii(ii(i.fi.fi, i.fi.se), i.se)); + n = v.size(); + + sort(all(v), [](const iii &a, const iii &b) { + if (a.fi.fi != b.fi.fi) + return a.fi.fi < b.fi.fi; + else if (a.fi.se != b.fi.se) + return a.fi.se > b.fi.se; + return a.se > b.se; + }); + + set<ll> S; + map<ll,ll> compress; + for (auto i : v) + S.insert(i.fi.se); + + ll k = 1LL; + for (auto i : S) + compress[i] = k++; + for (auto &i : v) + i.fi.se = compress[i.fi.se]; + + ll ans = 0, last = v[0].fi.fi; + for (int i = 0; ; ) { + for (; i < n && v[i].fi.fi == last; ++i) { + ll bst = max(bit.query(v[i].fi.se - 1) + v[i].se, + bit.query(v[i].fi.se)); + + bit.update(v[i].fi.se, bst); + ans = max(ans, bst); + } + + if (i >= n) break; + last = v[i].fi.fi; + } - cout << ans << ende; - return 0; + cout << ans << ende; + return 0; } diff --git a/contests/ICPC_LA17/G.cpp b/contests/ICPC_LA17/G.cpp index 48857566eba35eaed611fa24b7ed459d24a2444f..a0e509c1fe2f44a6072c2b07510df5b50e79c92e 100644 --- a/contests/ICPC_LA17/G.cpp +++ b/contests/ICPC_LA17/G.cpp @@ -27,54 +27,54 @@ map<ii,int> backw; int L[MAX], R[MAX], val[MAX]; struct comb { - ll pos[4]; + ll pos[4]; - comb() { mset(pos, 0); } + comb() { mset(pos, 0); } - static comb base() { - comb res; - res.pos[0] = res.pos[3] = 1; - return res; - } + static comb base() { + comb res; + res.pos[0] = res.pos[3] = 1; + return res; + } }; comb dfs(int x) { - comb res; - comb l = (L[x]) ? (dfs(L[x])) : (comb::base()); - comb r = (R[x]) ? (dfs(R[x])) : (comb::base()); - - for (int i = 0; i < 4; ++i) - for (int j = 0; j < 4; ++j) { - ii nand = ii(!(forw[i].fi && forw[j].fi), !(forw[i].se && forw[j].se)); - res.pos[backw[nand]] = (res.pos[backw[nand]] + - (l.pos[i] % MOD) * (r.pos[j] % MOD)) % MOD; + comb res; + comb l = (L[x]) ? (dfs(L[x])) : (comb::base()); + comb r = (R[x]) ? (dfs(R[x])) : (comb::base()); + + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 4; ++j) { + ii nand = ii(!(forw[i].fi && forw[j].fi), !(forw[i].se && forw[j].se)); + res.pos[backw[nand]] = (res.pos[backw[nand]] + + (l.pos[i] % MOD) * (r.pos[j] % MOD)) % MOD; + } + + if (val[x] == 0) { + res.pos[0] = (res.pos[0] + res.pos[2]) % MOD, res.pos[2] = 0; + res.pos[1] = (res.pos[1] + res.pos[3]) % MOD, res.pos[3] = 0; + } else if (val[x] == 1) { + res.pos[2] = (res.pos[2] + res.pos[0]) % MOD, res.pos[0] = 0; + res.pos[3] = (res.pos[3] + res.pos[1]) % MOD, res.pos[1] = 0; } - if (val[x] == 0) { - res.pos[0] = (res.pos[0] + res.pos[2]) % MOD, res.pos[2] = 0; - res.pos[1] = (res.pos[1] + res.pos[3]) % MOD, res.pos[3] = 0; - } else if (val[x] == 1) { - res.pos[2] = (res.pos[2] + res.pos[0]) % MOD, res.pos[0] = 0; - res.pos[3] = (res.pos[3] + res.pos[1]) % MOD, res.pos[1] = 0; - } - - return res; + return res; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int n; cin >> n; - for (int i = 1; i <= n; ++i) - cin >> L[i] >> R[i] >> val[i]; + int n; cin >> n; + for (int i = 1; i <= n; ++i) + cin >> L[i] >> R[i] >> val[i]; - forw[0] = ii(0, 0); backw[ii(0, 0)] = 0; - forw[1] = ii(0, 1); backw[ii(0, 1)] = 1; - forw[2] = ii(1, 0); backw[ii(1, 0)] = 2; - forw[3] = ii(1, 1); backw[ii(1, 1)] = 3; + forw[0] = ii(0, 0); backw[ii(0, 0)] = 0; + forw[1] = ii(0, 1); backw[ii(0, 1)] = 1; + forw[2] = ii(1, 0); backw[ii(1, 0)] = 2; + forw[3] = ii(1, 1); backw[ii(1, 1)] = 3; - comb ans = dfs(1); - cout << (ans.pos[1] + ans.pos[2]) % MOD << ende; - return 0; + comb ans = dfs(1); + cout << (ans.pos[1] + ans.pos[2]) % MOD << ende; + return 0; } diff --git a/contests/ICPC_LA17/H.cpp b/contests/ICPC_LA17/H.cpp index 0b1156ff53c3539f7ddb98ecd1277d97f790700c..06c28a89acb87de906ef4467b800fab44c91fbea 100644 --- a/contests/ICPC_LA17/H.cpp +++ b/contests/ICPC_LA17/H.cpp @@ -22,12 +22,12 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int a, b, c; cin >> a >> b >> c; - int d, e, f; cin >> d >> e >> f; + int a, b, c; cin >> a >> b >> c; + int d, e, f; cin >> d >> e >> f; - cout << max(0, d - a) + max(0, e - b) + max(0, f - c) << ende; - return 0; + cout << max(0, d - a) + max(0, e - b) + max(0, f - c) << ende; + return 0; } diff --git a/contests/ICPC_LA17/I.cpp b/contests/ICPC_LA17/I.cpp index 1056fd62d8bdce18fb0e535f6990ec428554d094..735e2cf81681299fde6d49d73dd52f3340209a99 100644 --- a/contests/ICPC_LA17/I.cpp +++ b/contests/ICPC_LA17/I.cpp @@ -31,55 +31,55 @@ int pare[MAX]; int size[MAX]; void make_set(int x) { - pare[x] = x; - size[x] = 1; + pare[x] = x; + size[x] = 1; } int find_set(int x) { - if (pare[x] != x) - pare[x] = find_set(pare[x]); - return pare[x]; + if (pare[x] != x) + pare[x] = find_set(pare[x]); + return pare[x]; } void union_set(int x, int y) { - x = find_set(x); - y = find_set(y); + x = find_set(x); + y = find_set(y); - if (x == y) - return; + if (x == y) + return; - if (size[x] > size[y]) - swap(x, y); + if (size[x] > size[y]) + swap(x, y); - pare[x] = y; - size[y] += size[x]; + pare[x] = y; + size[y] += size[x]; } int kruskal() { - sort(all(edges), [&](const iii &a, const iii &b) { - return a.se < b.se; - }); + sort(all(edges), [&](const iii &a, const iii &b) { + return a.se < b.se; + }); - int ans = 0; - for (int i = 0; i < MAX; i++) - make_set(i); + int ans = 0; + for (int i = 0; i < MAX; i++) + make_set(i); - for (int i = 0; i < edges.size(); i++) { - int pu = find_set(edges[i].fi.fi); - int pv = find_set(edges[i].fi.se); + for (int i = 0; i < edges.size(); i++) { + int pu = find_set(edges[i].fi.fi); + int pv = find_set(edges[i].fi.se); - if (pu != pv) { - mst[edges[i].fi] = true; + if (pu != pv) { + mst[edges[i].fi] = true; - graph[edges[i].fi.fi].pb(ii(edges[i].fi.se, edges[i].se)); - graph[edges[i].fi.se].pb(ii(edges[i].fi.fi, edges[i].se)); + graph[edges[i].fi.fi].pb(ii(edges[i].fi.se, edges[i].se)); + graph[edges[i].fi.se].pb(ii(edges[i].fi.fi, edges[i].se)); - ans += edges[i].se; - union_set(pu, pv); + ans += edges[i].se; + union_set(pu, pv); + } } - } - return ans; + return ans; } #define MAXLOG 20 @@ -89,84 +89,84 @@ int par[MAX][MAXLOG]; int cost[MAX][MAXLOG]; void dfs(int v, int p = -1, int c = 0) { - par[v][0] = p; - cost[v][0] = c; + par[v][0] = p; + cost[v][0] = c; - if (p != -1) - h[v] = h[p] + 1; + if (p != -1) + h[v] = h[p] + 1; - for (int i = 1; i < MAXLOG; ++i) - if (par[v][i - 1] != -1) { - par[v][i] = par[par[v][i - 1]][i - 1]; - cost[v][i] = max(cost[v][i], max(cost[par[v][i-1]][i-1], cost[v][i-1])); - } + for (int i = 1; i < MAXLOG; ++i) + if (par[v][i - 1] != -1) { + par[v][i] = par[par[v][i - 1]][i - 1]; + cost[v][i] = max(cost[v][i], max(cost[par[v][i-1]][i-1], cost[v][i-1])); + } - for (auto u : graph[v]) - if (p != u.fi) - dfs(u.fi, v, u.se); + for (auto u : graph[v]) + if (p != u.fi) + dfs(u.fi, v, u.se); } void preprocess(int v) { - memset(par, -1, sizeof par); - memset(cost, 0, sizeof cost); - dfs(v); + memset(par, -1, sizeof par); + memset(cost, 0, sizeof cost); + dfs(v); } int query(int p, int q) { - int ans = 0; + int ans = 0; - if (h[p] < h[q]) - swap(p, q); + if (h[p] < h[q]) + swap(p, q); - for (int i = MAXLOG - 1; i >= 0; --i) - if (par[p][i] != -1 && h[par[p][i]] >= h[q]) { - ans = max(ans, cost[p][i]); - p = par[p][i]; - } + for (int i = MAXLOG - 1; i >= 0; --i) + if (par[p][i] != -1 && h[par[p][i]] >= h[q]) { + ans = max(ans, cost[p][i]); + p = par[p][i]; + } - if (p == q) - return ans; + if (p == q) + return ans; - for (int i = MAXLOG - 1; i >= 0; --i) - if (par[p][i] != -1 && par[p][i] != par[q][i]) { - ans = max(ans, max(cost[p][i], cost[q][i])); - p = par[p][i]; - q = par[q][i]; - } + for (int i = MAXLOG - 1; i >= 0; --i) + if (par[p][i] != -1 && par[p][i] != par[q][i]) { + ans = max(ans, max(cost[p][i], cost[q][i])); + p = par[p][i]; + q = par[q][i]; + } - if (p == q) return ans; - else return max(ans, max(cost[p][0], cost[q][0])); + if (p == q) return ans; + else return max(ans, max(cost[p][0], cost[q][0])); } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, r; cin >> n >> r; - map<ii,int> M; - - for (int i = 0; i < r; ++i) { - int a, b, c; cin >> a >> b >> c; - a--, b--; - M[ii(a, b)] = c; - M[ii(b, a)] = c; - edges.pb(iii(ii(a, b), c)); - edges.pb(iii(ii(b, a), c)); - } - - int vmst = kruskal(); - preprocess(0); - - int q; cin >> q; - for (int i = 0; i < q; ++i) { - int a, b; cin >> a >> b; - a--, b--; - - if (mst[ii(a, b)] || mst[ii(b, a)]) - cout << vmst << ende; - else - cout << vmst - query(a, b) + M[ii(a, b)] << ende; - } - - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int n, r; cin >> n >> r; + map<ii,int> M; + + for (int i = 0; i < r; ++i) { + int a, b, c; cin >> a >> b >> c; + a--, b--; + M[ii(a, b)] = c; + M[ii(b, a)] = c; + edges.pb(iii(ii(a, b), c)); + edges.pb(iii(ii(b, a), c)); + } + + int vmst = kruskal(); + preprocess(0); + + int q; cin >> q; + for (int i = 0; i < q; ++i) { + int a, b; cin >> a >> b; + a--, b--; + + if (mst[ii(a, b)] || mst[ii(b, a)]) + cout << vmst << ende; + else + cout << vmst - query(a, b) + M[ii(a, b)] << ende; + } + + return 0; } diff --git a/contests/ICPC_LA17/J.cpp b/contests/ICPC_LA17/J.cpp index f7c4b7f7039593368ffd6284e1b030c310884dcd..86638a96ad5d4e58a74f5f876864e5710887e5cc 100644 --- a/contests/ICPC_LA17/J.cpp +++ b/contests/ICPC_LA17/J.cpp @@ -22,47 +22,47 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - string s; cin >> s; - int r = 0, n = s.size(); - for (int i = 0; i < n; ++i) - r += (s[i] == 'R'); + string s; cin >> s; + int r = 0, n = s.size(); + for (int i = 0; i < n; ++i) + r += (s[i] == 'R'); - if (r == n) - return cout << n - 1 << ende, 0; + if (r == n) + return cout << n - 1 << ende, 0; - vector<int> divs; - for (int i = 2; i*i <= n; ++i) - if (n % i == 0) { - divs.pb(i); - if (i != n / i) - divs.pb(n / i); - } + vector<int> divs; + for (int i = 2; i*i <= n; ++i) + if (n % i == 0) { + divs.pb(i); + if (i != n / i) + divs.pb(n / i); + } - vector<int> nums(n, 0); - for (int i = 2; i < n; ++i) - nums[__gcd(i, n)]++; + vector<int> nums(n, 0); + for (int i = 2; i < n; ++i) + nums[__gcd(i, n)]++; - int ans = 0; - for (auto i : divs) { - bool poss = false; - for (int j = 0; j < i; ++j) { - bool onlyr = true; - for (int k = j; k < n; k += i) - onlyr &= (s[k] == 'R'); + int ans = 0; + for (auto i : divs) { + bool poss = false; + for (int j = 0; j < i; ++j) { + bool onlyr = true; + for (int k = j; k < n; k += i) + onlyr &= (s[k] == 'R'); - if (onlyr) { - poss = true; - break; - } - } + if (onlyr) { + poss = true; + break; + } + } - if (poss) - ans += nums[i]; - } + if (poss) + ans += nums[i]; + } - cout << ans << ende; - return 0; + cout << ans << ende; + return 0; } diff --git a/contests/ICPC_LA18/A.cpp b/contests/ICPC_LA18/A.cpp index d59077bd6c4e60e655ce1aa64bb7b76e7130308f..f6025b7dbeb293434a245d8980ac3f5869aab0e0 100644 --- a/contests/ICPC_LA18/A.cpp +++ b/contests/ICPC_LA18/A.cpp @@ -22,15 +22,15 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - string s; cin >> s; - s.erase(s.begin() + s.size() - 3); - stringstream x(s); + string s; cin >> s; + s.erase(s.begin() + s.size() - 3); + stringstream x(s); - int r; x >> r; - cout << 36000 / __gcd(36000, r) << ende; + int r; x >> r; + cout << 36000 / __gcd(36000, r) << ende; - return 0; + return 0; } diff --git a/contests/ICPC_LA18/B.cpp b/contests/ICPC_LA18/B.cpp index a4eb7ff9e2bf9c907f60cbd6f64982a4eeaa6c90..4e37e5cf9382cc6364524b747ec7e2fbd03acf32 100644 --- a/contests/ICPC_LA18/B.cpp +++ b/contests/ICPC_LA18/B.cpp @@ -22,33 +22,33 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int n; cin >> n; - vector<int> v(n), pref(n); - for (auto &i : v) cin >> i; + int n; cin >> n; + vector<int> v(n), pref(n); + for (auto &i : v) cin >> i; - pref[0] = v[0]; - for (int i = 1; i < n; ++i) - pref[i] = pref[i-1] + v[i]; + pref[0] = v[0]; + for (int i = 1; i < n; ++i) + pref[i] = pref[i-1] + v[i]; - if (pref.back() % 2) - return cout << "N" << ende, 0; + if (pref.back() % 2) + return cout << "N" << ende, 0; - int beg = 0, ans = 0; - for (int i = 0; i < n; ++i) { - while (beg < i && pref[i] - pref[beg] > pref.back() / 2) - beg++; + int beg = 0, ans = 0; + for (int i = 0; i < n; ++i) { + while (beg < i && pref[i] - pref[beg] > pref.back() / 2) + beg++; - if (pref[i] - pref[beg] == (pref.back() / 2)) - ans++; - } + if (pref[i] - pref[beg] == (pref.back() / 2)) + ans++; + } - if (ans >= 2) - cout << "Y" << ende; - else - cout << "N" << ende; + if (ans >= 2) + cout << "Y" << ende; + else + cout << "N" << ende; - return 0; + return 0; } diff --git a/contests/ICPC_LA18/C.cpp b/contests/ICPC_LA18/C.cpp index ad43314d8c9b4f006e7d9239f33112c72f13da62..4f63e0d2d47447424375a4f0fd1a545b84996cc2 100644 --- a/contests/ICPC_LA18/C.cpp +++ b/contests/ICPC_LA18/C.cpp @@ -27,41 +27,41 @@ int d[MAX], c[MAX]; int dp[MAX][6][123]; int fix(int x) { - return min(x, 121); + return min(x, 121); } int solve(int i, int state, int mi) { - if (i == n) - return 0; + if (i == n) + return 0; - if (dp[i][state][mi] != -1) - return dp[i][state][mi]; + if (dp[i][state][mi] != -1) + return dp[i][state][mi]; - if (state == 0 || mi >= 120) - return dp[i][state][mi] = solve(i + 1, 1, fix(d[i])) + c[i]; + if (state == 0 || mi >= 120) + return dp[i][state][mi] = solve(i + 1, 1, fix(d[i])) + c[i]; - if (state == 1) - return dp[i][state][mi] = - min(solve(i + 1, state + 1, fix(mi + d[i])) + (c[i] / 2), - solve(i + 1, 1, fix(d[i])) + c[i]); - else - return dp[i][state][mi] = - min(solve(i + 1, (state + 1) % 6, fix(mi + d[i])) + (c[i] / 4), - solve(i + 1, 1, fix(d[i])) + c[i]); + if (state == 1) + return dp[i][state][mi] = + min(solve(i + 1, state + 1, fix(mi + d[i])) + (c[i] / 2), + solve(i + 1, 1, fix(d[i])) + c[i]); + else + return dp[i][state][mi] = + min(solve(i + 1, (state + 1) % 6, fix(mi + d[i])) + (c[i] / 4), + solve(i + 1, 1, fix(d[i])) + c[i]); } int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - cin >> n; - for (int i = 0; i < n; ++i) { - cin >> d[i] >> c[i]; - c[i] *= 100; - } + cin >> n; + for (int i = 0; i < n; ++i) { + cin >> d[i] >> c[i]; + c[i] *= 100; + } - mset(dp, -1); - int ans = solve(0, 0, 0); - cout << (ans / 100) << "." << setfill('0') << setw(2) << (ans % 100) << ende; - return 0; + mset(dp, -1); + int ans = solve(0, 0, 0); + cout << (ans / 100) << "." << setfill('0') << setw(2) << (ans % 100) << ende; + return 0; } diff --git a/contests/ICPC_LA18/E.cpp b/contests/ICPC_LA18/E.cpp index 556ea4c248a41f385fa32de23b7d9c89f753e829..4e88d080c1c32e276e373c34efc5dd83bf5ef075 100644 --- a/contests/ICPC_LA18/E.cpp +++ b/contests/ICPC_LA18/E.cpp @@ -22,41 +22,41 @@ using ll = long long; using ii = pair<int,int>; struct Point { - double x, y; - Point() {} - Point(double x, double y) : x(x), y(y) {} - Point operator-(Point a) { return Point(x - a.x, y - a.y); } + double x, y; + Point() {} + Point(double x, double y) : x(x), y(y) {} + Point operator-(Point a) { return Point(x - a.x, y - a.y); } }; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - ll n; cin >> n; - vector<Point> v(n); - for (auto &i : v) - cin >> i.x >> i.y; + ll n; cin >> n; + vector<Point> v(n); + for (auto &i : v) + cin >> i.x >> i.y; - ll ans = (n * (n - 1LL) * (n - 2LL)) / 6LL; - for (int i = 0; i < n; ++i) { - ll l = i + 1, r = i + n - 1; + ll ans = (n * (n - 1LL) * (n - 2LL)) / 6LL; + for (int i = 0; i < n; ++i) { + ll l = i + 1, r = i + n - 1; - for (int j = 0; j < 20; ++j) { - ll m = (l + r) / 2; + for (int j = 0; j < 20; ++j) { + ll m = (l + r) / 2; - Point a = v[(i+1)%n] - v[i]; - Point b = v[(m+1)%n] - v[m%n]; + Point a = v[(i+1)%n] - v[i]; + Point b = v[(m+1)%n] - v[m%n]; - double ang = (atan2(-(a.x*b.y - a.y*b.x), -(a.x*b.x + a.y*b.y)) * 180.0) / M_PI + 180.0; - if (ang > 180.0) - r = m; - else - l = m; - } + double ang = (atan2(-(a.x*b.y - a.y*b.x), -(a.x*b.x + a.y*b.y)) * 180.0) / M_PI + 180.0; + if (ang > 180.0) + r = m; + else + l = m; + } - ans -= ((l - i) * (l - i - 1LL)) / 2LL; - } + ans -= ((l - i) * (l - i - 1LL)) / 2LL; + } - cout << ans << ende; - return 0; + cout << ans << ende; + return 0; } diff --git a/contests/ICPC_LA18/F.cpp b/contests/ICPC_LA18/F.cpp index b21af32b31c520e6fd48e7e0664792c1c628f85c..459c870e2a6c369b4ef04717d44468403562acc9 100644 --- a/contests/ICPC_LA18/F.cpp +++ b/contests/ICPC_LA18/F.cpp @@ -24,105 +24,105 @@ using ii = pair<ll,ll>; struct ans_t { ll x, y, d; }; ans_t ext_gcd(ll a, ll b) { - if (a == 0) return {0, 1, b}; - ans_t e = ext_gcd(b % a, a); - return {e.y - (b/a) * e.x, e.x, e.d}; + if (a == 0) return {0, 1, b}; + ans_t e = ext_gcd(b % a, a); + return {e.y - (b/a) * e.x, e.x, e.d}; } 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) { - ans_t e = ext_gcd(n, m); + ans_t e = ext_gcd(n, m); - if ((a - b) % e.d != 0) - return {-1,-1}; + if ((a - b) % e.d != 0) + return {-1,-1}; - ll lcm = (m/e.d) * n; - ll ans = norm(a + e.x*(b-a) / e.d % (m/e.d)*n, lcm); - return {norm(ans, lcm), lcm}; + ll lcm = (m/e.d) * n; + ll ans = norm(a + e.x*(b-a) / e.d % (m/e.d)*n, lcm); + return {norm(ans, lcm), lcm}; } ll crt(vector<ll> a, vector<ll> m) { - ll ans = a[0]; - ll lcm = m[0]; + ll ans = a[0]; + ll lcm = m[0]; - int t = a.size(); - for (int i = 1; i < t; ++i) { - auto ss = crt_single(ans, lcm, a[i], m[i]); - if (ss.fi == -1) - return -1; + int t = a.size(); + for (int i = 1; i < t; ++i) { + auto ss = crt_single(ans, lcm, a[i], m[i]); + if (ss.fi == -1) + return -1; - ans = ss.fi; - lcm = ss.se; - } + ans = ss.fi; + lcm = ss.se; + } - return ans; + return ans; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int b, z; cin >> b >> z; - vector<vector<int>> mat(b, vector<int>(z+1)); - vector<vector<int>> time(z+1, vector<int>(501)); - vector<vector<ll>> a(z + 1, vector<ll>(b, -1)); - vector<vector<ll>> m(z + 1, vector<ll>(b, -1)); + int b, z; cin >> b >> z; + vector<vector<int>> mat(b, vector<int>(z+1)); + vector<vector<int>> time(z+1, vector<int>(501)); + vector<vector<ll>> a(z + 1, vector<ll>(b, -1)); + vector<vector<ll>> m(z + 1, vector<ll>(b, -1)); - for (auto &i : mat) - for (auto &j : i) cin >> j; + for (auto &i : mat) + for (auto &j : i) cin >> j; - for (int i = 0; i < b; ++i) { - int curr = mat[i][0]; - time[curr][0] |= (1 << i); + for (int i = 0; i < b; ++i) { + int curr = mat[i][0]; + time[curr][0] |= (1 << i); - for (int t = 1; t <= 500; ++t) { - curr = mat[i][curr]; - time[curr][t] |= (1 << i); + for (int t = 1; t <= 500; ++t) { + curr = mat[i][curr]; + time[curr][t] |= (1 << i); + } } - } - - for (int i = 1; i <= z; ++i) { - for (int t = 0; t <= 500; ++t) { - if (time[i][t] == (1 << b) - 1) - return cout << i << " " << t << ende, 0; - - for (int j = 0; j < b; ++j) - if (time[i][t] & (1 << j)) { - if (a[i][j] == -1) - a[i][j] = t; - else if (m[i][j] == -1) - m[i][j] = t - a[i][j]; + + for (int i = 1; i <= z; ++i) { + for (int t = 0; t <= 500; ++t) { + if (time[i][t] == (1 << b) - 1) + return cout << i << " " << t << ende, 0; + + for (int j = 0; j < b; ++j) + if (time[i][t] & (1 << j)) { + if (a[i][j] == -1) + a[i][j] = t; + else if (m[i][j] == -1) + m[i][j] = t - a[i][j]; + } } } - } - - ll zoo = 0; - ll ans = llinf*2; - for (int i = 1; i <= z; ++i) { - bool poss = true; - for (int j = 0; j < b; ++j) - if (a[i][j] == -1 || m[i][j] == -1) { - poss = false; - break; - } - - if (!poss) - continue; - - ll res = crt(a[i], m[i]); - if (res == -1) - continue; - else { - if (ans > res && res > 0) - zoo = i, ans = res; + + ll zoo = 0; + ll ans = llinf*2; + for (int i = 1; i <= z; ++i) { + bool poss = true; + for (int j = 0; j < b; ++j) + if (a[i][j] == -1 || m[i][j] == -1) { + poss = false; + break; + } + + if (!poss) + continue; + + ll res = crt(a[i], m[i]); + if (res == -1) + continue; + else { + if (ans > res && res > 0) + zoo = i, ans = res; + } } - } - if (ans == llinf*2) cout << "*" << ende; - else cout << zoo << " " << ans << ende; - return 0; + if (ans == llinf*2) cout << "*" << ende; + else cout << zoo << " " << ans << ende; + return 0; } diff --git a/contests/ICPC_LA18/H.cpp b/contests/ICPC_LA18/H.cpp index 80d33614102ae08059eb71f1bee312ebb0bbfd3f..c639b9f4b5b32930de22b7673a9915ea767870a2 100644 --- a/contests/ICPC_LA18/H.cpp +++ b/contests/ICPC_LA18/H.cpp @@ -23,75 +23,75 @@ using ii = pair<ll,ll>; using iii = pair<ll,ii>; ii operator+(const ii &a, const ii &b) { - return ii(a.fi + b.fi, a.se + b.se); + return ii(a.fi + b.fi, a.se + b.se); } struct Dijkstra { - int N; - vector<ll> dist; - vector<int> cont; - vector<vector<iii>> graph; - - Dijkstra(int N) : - N(N), dist(N, llinf), cont(N, 0), graph(N) - {} - - ll run(int s) { - set<iii> pq; - - ll ans = 0; - dist[s] = 0; - pq.insert(iii(0, ii(s, 0))); - - while (pq.size() != 0) { - iii top = *(pq.begin()); - pq.erase(pq.begin()); - - int u = top.se.fi; - if (cont[u]) - continue; - - cont[u] = 1; - ans += top.se.se; - - for (auto i : graph[u]) { - int v = i.fi; - ll wt = i.se.fi; - - if (!cont[v] && dist[v] >= top.fi + wt) { - dist[v] = top.fi + wt; - pq.insert(iii(dist[v], ii(v, i.se.se))); + int N; + vector<ll> dist; + vector<int> cont; + vector<vector<iii>> graph; + + Dijkstra(int N) : + N(N), dist(N, llinf), cont(N, 0), graph(N) + {} + + ll run(int s) { + set<iii> pq; + + ll ans = 0; + dist[s] = 0; + pq.insert(iii(0, ii(s, 0))); + + while (pq.size() != 0) { + iii top = *(pq.begin()); + pq.erase(pq.begin()); + + int u = top.se.fi; + if (cont[u]) + continue; + + cont[u] = 1; + ans += top.se.se; + + for (auto i : graph[u]) { + int v = i.fi; + ll wt = i.se.fi; + + if (!cont[v] && dist[v] >= top.fi + wt) { + dist[v] = top.fi + wt; + pq.insert(iii(dist[v], ii(v, i.se.se))); + } + } } - } - } - return ans; - } + return ans; + } }; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, m; cin >> n >> m; - Dijkstra d(n+2); - map<ii,ii> M; - for (int i = 0; i < m; ++i) { - int a, b; ll l, c; - cin >> a >> b >> l >> c; - if (M.find(ii(a, b)) != M.end()) { - M[ii(a, b)] = min(M[ii(a, b)], ii(l, c)); - M[ii(b, a)] = M[ii(a, b)]; - } else { - M[ii(a, b)] = {l, c}; - M[ii(b, a)] = {l, c}; + ios::sync_with_stdio(0); + cin.tie(0); + + int n, m; cin >> n >> m; + Dijkstra d(n+2); + map<ii,ii> M; + for (int i = 0; i < m; ++i) { + int a, b; ll l, c; + cin >> a >> b >> l >> c; + if (M.find(ii(a, b)) != M.end()) { + M[ii(a, b)] = min(M[ii(a, b)], ii(l, c)); + M[ii(b, a)] = M[ii(a, b)]; + } else { + M[ii(a, b)] = {l, c}; + M[ii(b, a)] = {l, c}; + } } - } - for (auto i : M) - d.graph[i.fi.fi].pb({i.fi.se, i.se}); + for (auto i : M) + d.graph[i.fi.fi].pb({i.fi.se, i.se}); - ll ans = d.run(1); - cout << ans << ende; - return 0; + ll ans = d.run(1); + cout << ans << ende; + return 0; } diff --git a/contests/ICPC_LA18/I.cpp b/contests/ICPC_LA18/I.cpp index 408da3c026e2498f23ae61a4e2e9f5b4035bdda8..6f5e50e2e90d0db489e2d87e2a82c6afe64747e6 100644 --- a/contests/ICPC_LA18/I.cpp +++ b/contests/ICPC_LA18/I.cpp @@ -26,40 +26,40 @@ int par[MAX], deg[MAX], lev[MAX]; vector<int> graph[MAX]; void dfs(int x, int l) { - lev[x] = l; - for (auto i : graph[x]) - dfs(i, l + 1); + lev[x] = l; + for (auto i : graph[x]) + dfs(i, l + 1); } int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int n; cin >> n; - for (int i = 2; i <= n; ++i) { - int x; cin >> par[i]; - deg[par[i]]++; - graph[par[i]].pb(i); - } + int n; cin >> n; + for (int i = 2; i <= n; ++i) { + int x; cin >> par[i]; + deg[par[i]]++; + graph[par[i]].pb(i); + } + + dfs(1, 0); + set<ii> S; + for (int i = 2; i <= n; ++i) + S.insert(ii(-lev[i], i)); - dfs(1, 0); - set<ii> S; - for (int i = 2; i <= n; ++i) - S.insert(ii(-lev[i], i)); - - int ans = 0; - while (S.size() > 0) { - ii curr = *S.begin(); - S.erase(S.begin()); + int ans = 0; + while (S.size() > 0) { + ii curr = *S.begin(); + S.erase(S.begin()); - if (deg[curr.se] >= 2 && deg[par[curr.se]] >= 3 && par[curr.se] != 1 && - S.find(ii(-lev[par[curr.se]], par[curr.se])) != S.end()) { - S.erase(ii(-lev[par[curr.se]], par[curr.se])); - deg[par[par[curr.se]]]--; - ans++; + if (deg[curr.se] >= 2 && deg[par[curr.se]] >= 3 && par[curr.se] != 1 && + S.find(ii(-lev[par[curr.se]], par[curr.se])) != S.end()) { + S.erase(ii(-lev[par[curr.se]], par[curr.se])); + deg[par[par[curr.se]]]--; + ans++; + } } - } - cout << ans << ende; - return 0; + cout << ans << ende; + return 0; } diff --git a/contests/ICPC_LA18/L.cpp b/contests/ICPC_LA18/L.cpp index 8f2c5c1ffb9fed0249d532dfaa320a74a5cca2c4..736ba3489d3271518283438e348520256984e494 100644 --- a/contests/ICPC_LA18/L.cpp +++ b/contests/ICPC_LA18/L.cpp @@ -24,19 +24,19 @@ using ii = pair<int,int>; using iii = pair<ii,int>; vector<int> sieve(int n) { - vector<int> primes; - vector<bool> is_prime(n+1, true); + vector<int> primes; + vector<bool> is_prime(n+1, true); - for (int p = 2; p*p <= n; ++p) - if (is_prime[p]) - for (int i = p*p; i <= n; i += p) - is_prime[i] = false; + for (int p = 2; p*p <= n; ++p) + if (is_prime[p]) + for (int i = p*p; i <= n; i += p) + is_prime[i] = false; - for (int p = 2; p <= n; ++p) - if (is_prime[p]) - primes.pb(p); + for (int p = 2; p <= n; ++p) + if (is_prime[p]) + primes.pb(p); - return primes; + return primes; } int N; @@ -47,78 +47,78 @@ int tree[4 * MAX]; #define right(x) ((x << 1) + 1) void build(int node = 1, int a = 0, int b = N - 1) { - if (a > b) - return; + if (a > b) + return; - if (a == b) { - tree[node] = v[a]; - return; - } + if (a == b) { + tree[node] = v[a]; + return; + } - build(left(node), a, (a + b) / 2); - build(right(node), 1 + (a + b) / 2, b); - tree[node] = tree[node * 2] + tree[node * 2 + 1]; + build(left(node), a, (a + b) / 2); + build(right(node), 1 + (a + b) / 2, b); + tree[node] = tree[node * 2] + tree[node * 2 + 1]; } void update(int idx, int val, int node = 1, int a = 0, int b = N - 1) { - if (a > b || a > idx || b < idx) - return; + if (a > b || a > idx || b < idx) + return; - if (a == b) { - tree[node] += val; - return; - } + if (a == b) { + tree[node] += val; + return; + } - update(idx, val, left(node), a, (a + b) / 2); - update(idx, val, right(node), 1 + (a + b) / 2, b); - tree[node] = tree[node * 2] + tree[node * 2 + 1]; + update(idx, val, left(node), a, (a + b) / 2); + update(idx, val, right(node), 1 + (a + b) / 2, b); + tree[node] = tree[node * 2] + tree[node * 2 + 1]; } int query(int i, int j, int node = 1, int a = 0, int b = N - 1) { - if (a > b || a > j || b < i) - return 0; + if (a > b || a > j || b < i) + return 0; - if (i <= a && b <= j) - return tree[node]; + if (i <= a && b <= j) + return tree[node]; - int q1 = query(i, j, left(node), a, (a + b) / 2); - int q2 = query(i, j, right(node), 1 + (a + b) / 2, b); - return q1 + q2; + int q1 = query(i, j, left(node), a, (a + b) / 2); + int q2 = query(i, j, right(node), 1 + (a + b) / 2, b); + return q1 + q2; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - vector<int> primes = sieve(100000); - - int q; cin >> q; - vector<iii> que(q); - for (int i = 0; i < q; ++i) { - int n, k; cin >> n >> k; - que[i] = {ii(k, n), i}; - } - - N = 100001; - fill(v, v+N, 1); - build(); - - vector<int> ans(q); - int curr = primes.size() - 1; - sort(rall(que)); - for (auto i : que) { - while (curr >= 0 && primes[curr] > i.fi.fi) { - for (int j = primes[curr]; j <= N; j += primes[curr]) - if (query(j, j) != 0) - update(j, -1); - - curr--; + ios::sync_with_stdio(0); + cin.tie(0); + + vector<int> primes = sieve(100000); + + int q; cin >> q; + vector<iii> que(q); + for (int i = 0; i < q; ++i) { + int n, k; cin >> n >> k; + que[i] = {ii(k, n), i}; } - ans[i.se] = query(2, i.fi.se); - } + N = 100001; + fill(v, v+N, 1); + build(); - for (int i = 0; i < q; ++i) - cout << ans[i] << ende; - return 0; + vector<int> ans(q); + int curr = primes.size() - 1; + sort(rall(que)); + for (auto i : que) { + while (curr >= 0 && primes[curr] > i.fi.fi) { + for (int j = primes[curr]; j <= N; j += primes[curr]) + if (query(j, j) != 0) + update(j, -1); + + curr--; + } + + ans[i.se] = query(2, i.fi.se); + } + + for (int i = 0; i < q; ++i) + cout << ans[i] << ende; + return 0; } diff --git a/contests/ICPC_LA18/M.cpp b/contests/ICPC_LA18/M.cpp index cf7e018c2b2fde82a3ecceb62bac2db6f1fcc708..f732f4248e4164b60f834dca9e6f072107d72256 100644 --- a/contests/ICPC_LA18/M.cpp +++ b/contests/ICPC_LA18/M.cpp @@ -22,18 +22,18 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n; cin >> n; - int past = 0, ans = 0; - for (int i = 0; i < n; ++i) { - int x; cin >> x; - if (x > past) - ans++; - past = x; - } - - cout << ans << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int n; cin >> n; + int past = 0, ans = 0; + for (int i = 0; i < n; ++i) { + int x; cin >> x; + if (x > past) + ans++; + past = x; + } + + cout << ans << ende; + return 0; } diff --git a/contests/ICPC_LA19/E.cpp b/contests/ICPC_LA19/E.cpp index 70612c0d8d3060bde1157a27db2f906de632b08e..a418e434966bcdad0b1cce0f6f7c00c6f9ed73e9 100644 --- a/contests/ICPC_LA19/E.cpp +++ b/contests/ICPC_LA19/E.cpp @@ -22,22 +22,22 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - string s; cin >> s; s += s; - int x; cin >> x; - int n = s.size(); + string s; cin >> s; s += s; + int x; cin >> x; + int n = s.size(); - vector<int> last(n); - last[n-1] = (s[n-1] == 'E') ? n - 1 : inf; - for (int i = n - 2; i >= 0; --i) - last[i] = (s[i] == 'E') ? i : last[i+1]; + vector<int> last(n); + last[n-1] = (s[n-1] == 'E') ? n - 1 : inf; + for (int i = n - 2; i >= 0; --i) + last[i] = (s[i] == 'E') ? i : last[i+1]; - ll ans = 0LL; - for (int i = 0; i < n/2; ++i) - ans += max(0, x - (last[i] - i)); + ll ans = 0LL; + for (int i = 0; i < n/2; ++i) + ans += max(0, x - (last[i] - i)); - cout << ans << ende; - return 0; + cout << ans << ende; + return 0; } diff --git a/contests/ICPC_LA19/I.cpp b/contests/ICPC_LA19/I.cpp index b493ad468acf6d7dc8614104aae83a0fbacad978..c3c1aa40a96cc6b0e7bb4300d1fec457334e8440 100644 --- a/contests/ICPC_LA19/I.cpp +++ b/contests/ICPC_LA19/I.cpp @@ -25,31 +25,31 @@ int dp[2010], foi[2010]; vector<int> graph[2010]; ll solve(int x, int l) { - if (x >= l) return foi[x] = 1; - if (dp[x] != -1) return dp[x]; + if (x >= l) return foi[x] = 1; + if (dp[x] != -1) return dp[x]; - ll ans = 0; - for (auto i : graph[x]) - ans = (ans + solve(i, l)) % MOD; - return dp[x] = ans; + ll ans = 0; + for (auto i : graph[x]) + ans = (ans + solve(i, l)) % MOD; + return dp[x] = ans; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, l; cin >> n >> l; - for (int i = 0; i < l; ++i) { - int k; cin >> k; - for (int j = 0; j < k; ++j) { - int x; cin >> x; x--; - graph[i].pb(x); + ios::sync_with_stdio(0); + cin.tie(0); + + int n, l; cin >> n >> l; + for (int i = 0; i < l; ++i) { + int k; cin >> k; + for (int j = 0; j < k; ++j) { + int x; cin >> x; x--; + graph[i].pb(x); + } } - } - mset(dp, -1); - ll b = solve(0, l); - ll a = accumulate(foi + l, foi + 2010, 0); - cout << b << " " << a << ende; - return 0; + mset(dp, -1); + ll b = solve(0, l); + ll a = accumulate(foi + l, foi + 2010, 0); + cout << b << " " << a << ende; + return 0; } diff --git a/contests/ICPC_LA19/K.cpp b/contests/ICPC_LA19/K.cpp index 5f3f19ae6dccd98f3a744f66f748255f72be39d2..087ece4422f443a1e3fd36fd14cb3fabc63330da 100644 --- a/contests/ICPC_LA19/K.cpp +++ b/contests/ICPC_LA19/K.cpp @@ -22,42 +22,42 @@ using ll = long long; using ii = pair<ll,ll>; void mult(vector<ll> &ans, vector<ll> a, ii b) { - ans.resize(a.size() + 2); - fill(all(ans), 0); - for (int i = 0; i < a.size(); ++i) { - ans[i+0] += a[i] * b.fi; - ans[i+1] += a[i] * b.se; - } + ans.resize(a.size() + 2); + fill(all(ans), 0); + for (int i = 0; i < a.size(); ++i) { + ans[i+0] += a[i] * b.fi; + ans[i+1] += a[i] * b.se; + } } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - string s; cin >> s; - vector<ii> v; - for (int i = 1; i < s.size(); ++i) - if (s[i] != s[i-1]) - v.pb({1, -(2*i + 1)}); - - if (v.size() == 0) { - cout << 0 << ende; - return cout << ((s[0] == 'A') ? -1 : 1) << ende, 0; - } - - vector<ll> ans = {v[0].fi, v[0].se}; - for (int i = 1; i < v.size(); ++i) - mult(ans, ans, v[i]); - - ll mul = 1LL; - if ((v.size() % 2 && s[0] == 'H') || (v.size() % 2 == 0 && s[0] == 'A')) - mul *= -1LL; - - cout << v.size() << ende; - for (int i = 0; i <= v.size(); ++i) { - if (i) cout << " "; - cout << ans[i] * mul; - } - cout << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + string s; cin >> s; + vector<ii> v; + for (int i = 1; i < s.size(); ++i) + if (s[i] != s[i-1]) + v.pb({1, -(2*i + 1)}); + + if (v.size() == 0) { + cout << 0 << ende; + return cout << ((s[0] == 'A') ? -1 : 1) << ende, 0; + } + + vector<ll> ans = {v[0].fi, v[0].se}; + for (int i = 1; i < v.size(); ++i) + mult(ans, ans, v[i]); + + ll mul = 1LL; + if ((v.size() % 2 && s[0] == 'H') || (v.size() % 2 == 0 && s[0] == 'A')) + mul *= -1LL; + + cout << v.size() << ende; + for (int i = 0; i <= v.size(); ++i) { + if (i) cout << " "; + cout << ans[i] * mul; + } + cout << ende; + return 0; } diff --git a/contests/ICPC_LA19/L.cpp b/contests/ICPC_LA19/L.cpp index 4ba4a2052774b4c129c2baf2a0b652aa8aada1cd..029c3584d1182a166ef88595cabbd0079dedb53d 100644 --- a/contests/ICPC_LA19/L.cpp +++ b/contests/ICPC_LA19/L.cpp @@ -25,42 +25,42 @@ int mat[1010][1010]; int sum[1010][1010]; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, m; cin >> n >> m; - vector<string> v(n); - for (auto &i : v) cin >> i; - - for (int i = 0; i < n; ++i) - for (int j = 1; j < m; ++j) - mat[i][j-1] = (v[i][j] == v[i][j-1]); - - for (int i = 1; i < m; ++i) - sum[1][i] = mat[0][i-1]; - - for (int i = 2; i <= n; ++i) - for (int j = 1; j < m; ++j) - sum[i][j] = mat[i-1][j-1] + sum[i-1][j]; - - for (int i = 1; i <= n; ++i) - for (int j = 2; j < m; ++j) - sum[i][j] += sum[i][j-1]; - - auto query = [&](int i0, int j0, int i1, int j1) { - return sum[i1][j1] - sum[i0-1][j1] - sum[i1][j0-1] + sum[i0-1][j0-1]; - }; - - int ans = 1; - for (int i = 1; i <= n; ++i) - for (int j = 1; j < m; ++j) { - int k = 1; - for (int b = min(n, m) + 1; b > 0; b /= 2) - while (i+k+b-1 <= n && i+k+b-2 <= m && query(i, j, i+b+k-1, j+b+k-2) == (k+b)*(k+b-1)) - k += b; - ans = max(ans, k*k); - } - - cout << ans << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int n, m; cin >> n >> m; + vector<string> v(n); + for (auto &i : v) cin >> i; + + for (int i = 0; i < n; ++i) + for (int j = 1; j < m; ++j) + mat[i][j-1] = (v[i][j] == v[i][j-1]); + + for (int i = 1; i < m; ++i) + sum[1][i] = mat[0][i-1]; + + for (int i = 2; i <= n; ++i) + for (int j = 1; j < m; ++j) + sum[i][j] = mat[i-1][j-1] + sum[i-1][j]; + + for (int i = 1; i <= n; ++i) + for (int j = 2; j < m; ++j) + sum[i][j] += sum[i][j-1]; + + auto query = [&](int i0, int j0, int i1, int j1) { + return sum[i1][j1] - sum[i0-1][j1] - sum[i1][j0-1] + sum[i0-1][j0-1]; + }; + + int ans = 1; + for (int i = 1; i <= n; ++i) + for (int j = 1; j < m; ++j) { + int k = 1; + for (int b = min(n, m) + 1; b > 0; b /= 2) + while (i+k+b-1 <= n && i+k+b-2 <= m && query(i, j, i+b+k-1, j+b+k-2) == (k+b)*(k+b-1)) + k += b; + ans = max(ans, k*k); + } + + cout << ans << ende; + return 0; } diff --git a/contests/ICPC_LA19/M.cpp b/contests/ICPC_LA19/M.cpp index e5fb8446769bb4f6564a82ff86b565c653512624..e7ef23cce0687d6df2cfc3f0d500e1031ef2625a 100644 --- a/contests/ICPC_LA19/M.cpp +++ b/contests/ICPC_LA19/M.cpp @@ -22,24 +22,24 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, x; cin >> n >> x; - vector<int> v(n); - for (auto &i : v) cin >> i; - - int ans = 0; - for (int i = 0; i < n; ++i) { - int cnt = 1; - for (int j = i+1; j < n; ++j) - if (v[j] - v[j-1] <= x) - cnt++; - else - break; - ans = max(ans, cnt); - } - - cout << ans << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int n, x; cin >> n >> x; + vector<int> v(n); + for (auto &i : v) cin >> i; + + int ans = 0; + for (int i = 0; i < n; ++i) { + int cnt = 1; + for (int j = i+1; j < n; ++j) + if (v[j] - v[j-1] <= x) + cnt++; + else + break; + ans = max(ans, cnt); + } + + cout << ans << ende; + return 0; } diff --git a/contests/SBC14/A.cpp b/contests/SBC14/A.cpp index 159d22c9cc51b63cfbe17a37b2e5d4f38550df7d..293f3db394b24e201b4e4709817837d96fa6aa84 100644 --- a/contests/SBC14/A.cpp +++ b/contests/SBC14/A.cpp @@ -20,10 +20,10 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int x, y; cin >> x >> y; - cout << ((y - 1) / (y - x)) + 1 << ende; - return 0; + int x, y; cin >> x >> y; + cout << ((y - 1) / (y - x)) + 1 << ende; + return 0; } diff --git a/contests/SBC14/B.cpp b/contests/SBC14/B.cpp index 98e0d0087974a68606065dd7be9883176e060159..9f7d335c4173584f7e83aebacbc851460687a0fd 100644 --- a/contests/SBC14/B.cpp +++ b/contests/SBC14/B.cpp @@ -20,17 +20,17 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - ll n; cin >> n; - ll num = 2 % (n + 1); - int ans = 1; - while (true) { - if (num == 1) - return cout << ans << ende, 0; - num = (num * 2) % (n + 1); - ans++; - } - return 0; + ll n; cin >> n; + ll num = 2 % (n + 1); + int ans = 1; + while (true) { + if (num == 1) + return cout << ans << ende, 0; + num = (num * 2) % (n + 1); + ans++; + } + return 0; } diff --git a/contests/SBC14/C.cpp b/contests/SBC14/C.cpp index 57cf8930c67de1ed7217b2fa7cb5de3f4fe10461..e6773de88fec72b69ac34d5e5f7d37f271fdf462 100644 --- a/contests/SBC14/C.cpp +++ b/contests/SBC14/C.cpp @@ -22,28 +22,28 @@ using ii = pair<int,int>; struct plane { ll a, b, c, d; }; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int m, n; cin >> m >> n; - vector<plane> p(m); - for (int i = 0; i < m; ++i) { - ll a, b, c, d; cin >> a >> b >> c >> d; - p[i] = {a, b, c, d}; - } - - map<string,int> M; - for (int i = 0; i < n; ++i) { - string st; - ll a, b, c; cin >> a >> b >> c; - for (int j = 0; j < m; ++j) - st.pb((p[j].a*a + p[j].b*b + p[j].c*c > p[j].d) + '0'); - M[st] += 1; - } - - int ans = 0; - for (auto &i : M) - ans = max(ans, i.se); - cout << ans << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int m, n; cin >> m >> n; + vector<plane> p(m); + for (int i = 0; i < m; ++i) { + ll a, b, c, d; cin >> a >> b >> c >> d; + p[i] = {a, b, c, d}; + } + + map<string,int> M; + for (int i = 0; i < n; ++i) { + string st; + ll a, b, c; cin >> a >> b >> c; + for (int j = 0; j < m; ++j) + st.pb((p[j].a*a + p[j].b*b + p[j].c*c > p[j].d) + '0'); + M[st] += 1; + } + + int ans = 0; + for (auto &i : M) + ans = max(ans, i.se); + cout << ans << ende; + return 0; } diff --git a/contests/SBC14/F.cpp b/contests/SBC14/F.cpp index af8af4adf05122e68fed24c579ca741715ba5ddb..66e4317330a0e75b4aef63e7e0a46291782fbf54 100644 --- a/contests/SBC14/F.cpp +++ b/contests/SBC14/F.cpp @@ -22,41 +22,41 @@ using ii = pair<int,int>; ll mat[110*110], ans[110*110], aux[110*110]; void mult(ll *a, ll *b, ll *res, int n) { - for (int i = 0; i < n; ++i) - for (int j = 0; j < n; ++j) { - aux[i*n+j] = 0; - for (int k = 0; k < n; ++k) - aux[i*n+j] = (aux[i*n+j] + a[i*n+k] * b[k*n+j]) % MOD; - } + for (int i = 0; i < n; ++i) + for (int j = 0; j < n; ++j) { + aux[i*n+j] = 0; + for (int k = 0; k < n; ++k) + aux[i*n+j] = (aux[i*n+j] + a[i*n+k] * b[k*n+j]) % MOD; + } - memcpy(res, aux, sizeof aux); + memcpy(res, aux, sizeof aux); } void bin_exp(ll e, int n) { - mset(ans, 0); - for (int i = 0; i < n; ++i) - ans[i*n+i] = 1; - - while (e) { - if (e & 1) mult(ans, mat, ans, n); - e >>= 1; - mult(mat, mat, mat, n); - } + mset(ans, 0); + for (int i = 0; i < n; ++i) + ans[i*n+i] = 1; + + while (e) { + if (e & 1) mult(ans, mat, ans, n); + e >>= 1; + mult(mat, mat, mat, n); + } } int main() { - int n; ll l; - while (scanf("%d %lld", &n, &l) != EOF) { - int s, t, x; cin >> s >> t; s--, t--; - mset(mat, 0); - for (int i = 0; i < n; ++i) - for (int j = 0; j < 4; ++j) { - scanf("%d", &x); x--; - mat[i*n+x]++; - } - - bin_exp(l, n); - printf("%lld\n", ans[s*n + t] % MOD); - } - return 0; + int n; ll l; + while (scanf("%d %lld", &n, &l) != EOF) { + int s, t, x; cin >> s >> t; s--, t--; + mset(mat, 0); + for (int i = 0; i < n; ++i) + for (int j = 0; j < 4; ++j) { + scanf("%d", &x); x--; + mat[i*n+x]++; + } + + bin_exp(l, n); + printf("%lld\n", ans[s*n + t] % MOD); + } + return 0; } diff --git a/contests/SBC14/G.cpp b/contests/SBC14/G.cpp index b38b7ba2679d3cf92219590bfb898a457d4d1256..33c03d2b4e4b7c2369dacfb1ec0afb0f0bfcf33e 100644 --- a/contests/SBC14/G.cpp +++ b/contests/SBC14/G.cpp @@ -21,64 +21,64 @@ using ii = pair<int,int>; using pii = pair<ii,ii>; struct elem { - int x, y, l, u, d; + int x, y, l, u, d; }; ii get(char x) { - if (x >= 'a' && x <= 'j') - return {1 << (x - 'a'), 0}; - return {0, 1 << (x - 'A')}; + if (x >= 'a' && x <= 'j') + return {1 << (x - 'a'), 0}; + return {0, 1 << (x - 'A')}; } map<pii,int> foi; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - vector<int> dx = {-1, 1, 0, 0}; - vector<int> dy = {0, 0, 1, -1}; - - int n; cin >> n; - vector<string> v(n); - for (auto &i : v) - cin >> i; - - queue<elem> Q; - ii val = get(v[0][0]); - Q.push({0, 0, val.fi, val.se, 1}); - foi[pii(ii(0,0),ii(val.fi,val.fi))] = 1; - int ans = inf; - - while (!Q.empty()) { - elem u = Q.front(); Q.pop(); - if (u.x == n - 1 && u.y == n - 1) - ans = min(ans, u.d); - - for (int i = 0; i < 4; ++i) { - int x = u.x + dx[i]; - int y = u.y + dy[i]; - - if (x >= 0 && x < n && y >= 0 && y < n) { - val = get(v[x][y]); - if (val.fi) { - if (!(u.u & val.fi)) - if (!foi[pii(ii(x,y),ii(val.fi|u.l,u.u))]) { - Q.push({x, y, val.fi | u.l, u.u, u.d + 1}); - foi[pii(ii(x,y),ii(val.fi|u.l,u.u))] = 1; - } - } else { - if (!(u.l & val.se)) - if (!foi[pii(ii(x,y),ii(u.l,val.se | u.u))]) { - Q.push({x, y, u.l, val.se | u.u, u.d + 1}); - foi[pii(ii(x,y),ii(u.l,val.se|u.u))] = 1; + ios::sync_with_stdio(0); + cin.tie(0); + + vector<int> dx = {-1, 1, 0, 0}; + vector<int> dy = {0, 0, 1, -1}; + + int n; cin >> n; + vector<string> v(n); + for (auto &i : v) + cin >> i; + + queue<elem> Q; + ii val = get(v[0][0]); + Q.push({0, 0, val.fi, val.se, 1}); + foi[pii(ii(0,0),ii(val.fi,val.fi))] = 1; + int ans = inf; + + while (!Q.empty()) { + elem u = Q.front(); Q.pop(); + if (u.x == n - 1 && u.y == n - 1) + ans = min(ans, u.d); + + for (int i = 0; i < 4; ++i) { + int x = u.x + dx[i]; + int y = u.y + dy[i]; + + if (x >= 0 && x < n && y >= 0 && y < n) { + val = get(v[x][y]); + if (val.fi) { + if (!(u.u & val.fi)) + if (!foi[pii(ii(x,y),ii(val.fi|u.l,u.u))]) { + Q.push({x, y, val.fi | u.l, u.u, u.d + 1}); + foi[pii(ii(x,y),ii(val.fi|u.l,u.u))] = 1; + } + } else { + if (!(u.l & val.se)) + if (!foi[pii(ii(x,y),ii(u.l,val.se | u.u))]) { + Q.push({x, y, u.l, val.se | u.u, u.d + 1}); + foi[pii(ii(x,y),ii(u.l,val.se|u.u))] = 1; + } + } } } - } } - } - if (ans == inf) cout << -1 << ende; - else cout << ans << ende; - return 0; + if (ans == inf) cout << -1 << ende; + else cout << ans << ende; + return 0; } diff --git a/contests/SBC14/H.cpp b/contests/SBC14/H.cpp index 6972a43f3385f4b5ee0c1cbedefdd9a2d9560080..925e1ef7d503a27aa91253c7213d9511c0e0470b 100644 --- a/contests/SBC14/H.cpp +++ b/contests/SBC14/H.cpp @@ -20,21 +20,21 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int ans = 0; - int n, m; cin >> n >> m; - for (int i = 0; i < n; ++i) { - int cnt = 0; - for (int j = 0; j < m; ++j) { - int x; cin >> x; - cnt += (x != 0); + ios::sync_with_stdio(0); + cin.tie(0); + + int ans = 0; + int n, m; cin >> n >> m; + for (int i = 0; i < n; ++i) { + int cnt = 0; + for (int j = 0; j < m; ++j) { + int x; cin >> x; + cnt += (x != 0); + } + if (cnt == m) + ans++; } - if (cnt == m) - ans++; - } - cout << ans << ende; - return 0; + cout << ans << ende; + return 0; } diff --git a/contests/SBC14/I.cpp b/contests/SBC14/I.cpp index bbc0afffe93f41e556d5805600abc5f9d5c31010..5781eaffd2882163d47bd84675bd55917fd26e6d 100644 --- a/contests/SBC14/I.cpp +++ b/contests/SBC14/I.cpp @@ -20,70 +20,70 @@ using ll = long long; using ii = pair<int,int>; vector<int> sieve(int n) { - vector<int> primes; - vector<int> is_prime(n + 1, 1); + vector<int> primes; + vector<int> is_prime(n + 1, 1); - for (int p = 2; p*p <= n; ++p) - if (is_prime[p]) - for (int i = p*p; i <= n; i += p) - is_prime[i] = false; + for (int p = 2; p*p <= n; ++p) + if (is_prime[p]) + for (int i = p*p; i <= n; i += p) + is_prime[i] = false; - for (int p = 2; p <= n; ++p) - if (is_prime[p]) - primes.pb(p); + for (int p = 2; p <= n; ++p) + if (is_prime[p]) + primes.pb(p); - return primes; + return primes; } struct ans_t { ll x, y, d; }; ans_t ext_gcd(ll a, ll b) { - if (a == 0) return {0, 1, b}; - ans_t e = ext_gcd(b % a, a); - return {e.y - (b/a)*e.x, e.x, e.d}; + if (a == 0) return {0, 1, b}; + ans_t e = ext_gcd(b % a, a); + return {e.y - (b/a)*e.x, e.x, e.d}; } int extended_euclidean(int a, int m) { - ans_t g = ext_gcd(a, m); - return (g.x % m + m) % m; + ans_t g = ext_gcd(a, m); + return (g.x % m + m) % m; } ll bin_exp(ll a, ll e, ll M = MOD) { - ll x = 1; - while (e) { - if (e & 1) x = (x * a) % M; - e >>= 1; - a = (a * a) % M; - } - return x % M; + ll x = 1; + while (e) { + if (e & 1) x = (x * a) % M; + e >>= 1; + a = (a * a) % M; + } + return x % M; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); + + ll n, e, c; cin >> n >> e >> c; + vector<int> primes = sieve((int) sqrt(n)+1); - ll n, e, c; cin >> n >> e >> c; - vector<int> primes = sieve((int) sqrt(n)+1); - - for (int i = 0; i < primes.size() && primes[i]*primes[i] <= n; ++i) { - if (n % primes[i] == 0) { - ll p = primes[i]; - ll q = n / p; + for (int i = 0; i < primes.size() && primes[i]*primes[i] <= n; ++i) { + if (n % primes[i] == 0) { + ll p = primes[i]; + ll q = n / p; - if (p % 2 == 0 || q % 2 == 0) - continue; + if (p % 2 == 0 || q % 2 == 0) + continue; - ll phi = (p - 1) * (q - 1); - if (e >= phi || __gcd(phi, e) != 1) - continue; + ll phi = (p - 1) * (q - 1); + if (e >= phi || __gcd(phi, e) != 1) + continue; - ll d = extended_euclidean(e, phi); - ll m = bin_exp(c, d, n); + ll d = extended_euclidean(e, phi); + ll m = bin_exp(c, d, n); - if (bin_exp(m, e, n) == c && m > 0) - return cout << m << ende, 0; + if (bin_exp(m, e, n) == c && m > 0) + return cout << m << ende, 0; + } } - } - return 0; + return 0; } diff --git a/contests/SBC14/K.cpp b/contests/SBC14/K.cpp index 007b9e7bf7995babdc13eaa9b4837153a1c0312b..dda48109a6ba4b1ebf8b38cae210628dfb470341 100644 --- a/contests/SBC14/K.cpp +++ b/contests/SBC14/K.cpp @@ -20,49 +20,49 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - double c; - int n; cin >> c >> n; + double c; + int n; cin >> c >> n; - vector<double> v(n); - for (auto &i : v) cin >> i; + vector<double> v(n); + for (auto &i : v) cin >> i; - double l = v[0] + EPS, r = v[1]; - for (int i = 0; i < 30; ++i) { - double m = (l + r) / 2.0; - double cc = m + (c / n); + double l = v[0] + EPS, r = v[1]; + for (int i = 0; i < 30; ++i) { + double m = (l + r) / 2.0; + double cc = m + (c / n); - int k = 1; - int whi = 0; - for (int j = 1; j < n; j = k) { - while (k < n && v[k] < cc) k++; - if (k == n) - if (v[0] + c < cc) - k++; + int k = 1; + int whi = 0; + for (int j = 1; j < n; j = k) { + while (k < n && v[k] < cc) k++; + if (k == n) + if (v[0] + c < cc) + k++; - if (k - j > 1) { - whi = 1; - break; - } + if (k - j > 1) { + whi = 1; + break; + } - if (k - j == 0) { - whi = 2; - break; - } + if (k - j == 0) { + whi = 2; + break; + } - cc += (c / n); - } + cc += (c / n); + } - if (whi == 0) { - return cout << "S" << ende, 0; - } else if (whi == 1) - r = m; - else - l = m; - } + if (whi == 0) { + return cout << "S" << ende, 0; + } else if (whi == 1) + r = m; + else + l = m; + } - cout << "N" << ende; - return 0; + cout << "N" << ende; + return 0; } diff --git a/contests/SBC15/A.cpp b/contests/SBC15/A.cpp index 0c1b5829f6cecaca138465662d72eab932a1329f..ec67d1d2a73a6487bf7dff9dafd59022dee39a8b 100644 --- a/contests/SBC15/A.cpp +++ b/contests/SBC15/A.cpp @@ -26,42 +26,42 @@ vector<ii> graph[MAX]; vector<ii> gg[MAX]; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int c, v; cin >> c >> v; - for (int i = 0; i < v; ++i) { - int a, b, w; cin >> a >> b >> w; - graph[a].pb({b, w}); - graph[b].pb({a, w}); - } + int c, v; cin >> c >> v; + for (int i = 0; i < v; ++i) { + int a, b, w; cin >> a >> b >> w; + graph[a].pb({b, w}); + graph[b].pb({a, w}); + } - for (int i = 1; i <= c; ++i) - for (auto j : graph[i]) - for (auto k : graph[j.fi]) - gg[i].pb({k.fi, j.se + k.se}); + for (int i = 1; i <= c; ++i) + for (auto j : graph[i]) + for (auto k : graph[j.fi]) + gg[i].pb({k.fi, j.se + k.se}); - vector<int> vis(c + 1, 0); - vector<int> dist(c + 1, inf); + vector<int> vis(c + 1, 0); + vector<int> dist(c + 1, inf); - set<ii> pq; - pq.insert({0, 1}); - dist[1] = 0; - while (!pq.empty()) { - int u = pq.begin()->se; - pq.erase(pq.begin()); + set<ii> pq; + pq.insert({0, 1}); + dist[1] = 0; + while (!pq.empty()) { + int u = pq.begin()->se; + pq.erase(pq.begin()); - if (vis[u]) continue; - vis[u] = 1; + if (vis[u]) continue; + vis[u] = 1; - for (auto i : gg[u]) - if (!vis[i.fi] && dist[i.fi] > dist[u] + i.se) { - dist[i.fi] = dist[u] + i.se; - pq.insert({dist[i.fi], i.fi}); - } - } + for (auto i : gg[u]) + if (!vis[i.fi] && dist[i.fi] > dist[u] + i.se) { + dist[i.fi] = dist[u] + i.se; + pq.insert({dist[i.fi], i.fi}); + } + } - if (dist[c] == inf) dist[c] = -1; - cout << dist[c] << ende; - return 0; + if (dist[c] == inf) dist[c] = -1; + cout << dist[c] << ende; + return 0; } diff --git a/contests/SBC15/B.cpp b/contests/SBC15/B.cpp index 417f7b039e06fd3d31fc82ebec443ba0b4a0d2cf..308acee9c535793517633a4dfb41954c43cb550d 100644 --- a/contests/SBC15/B.cpp +++ b/contests/SBC15/B.cpp @@ -22,21 +22,21 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int n, c; cin >> n >> c; - vector<int> v(n); - vector<vector<int>> dp(n, vector<int>(2)); + int n, c; cin >> n >> c; + vector<int> v(n); + vector<vector<int>> dp(n, vector<int>(2)); - for (auto &i : v) cin >> i; + for (auto &i : v) cin >> i; - dp[n-1] = {0, v[n-1]}; - for (int i = n - 2; i >= 0; --i) { - dp[i][1] = max(dp[i + 1][0] + v[i], dp[i + 1][1]); - dp[i][0] = max(dp[i + 1][0], dp[i + 1][1] - (v[i] + c)); - } + dp[n-1] = {0, v[n-1]}; + for (int i = n - 2; i >= 0; --i) { + dp[i][1] = max(dp[i + 1][0] + v[i], dp[i + 1][1]); + dp[i][0] = max(dp[i + 1][0], dp[i + 1][1] - (v[i] + c)); + } - cout << max(0, dp[0][0]) << ende; - return 0; + cout << max(0, dp[0][0]) << ende; + return 0; } diff --git a/contests/SBC15/C.cpp b/contests/SBC15/C.cpp index 5edde77df31b2e90c095d299f07d6ec9568614f4..e338645818c7389d70a464c94e325410655d6b77 100644 --- a/contests/SBC15/C.cpp +++ b/contests/SBC15/C.cpp @@ -22,11 +22,11 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int a, b; cin >> a >> b; - cout << max(a, b) << ende; + int a, b; cin >> a >> b; + cout << max(a, b) << ende; - return 0; + return 0; } diff --git a/contests/SBC15/D.cpp b/contests/SBC15/D.cpp index b17fea0ee3fac144c3367182a11c9fba66381c43..bcdc66831f8df90af74734849b2c7bfc0d5fef32 100644 --- a/contests/SBC15/D.cpp +++ b/contests/SBC15/D.cpp @@ -25,70 +25,70 @@ int c[101], r[101]; string mat[101][101]; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int n, m; cin >> n >> m; + int n, m; cin >> n >> m; - int k = 0; - map<string,int> M; - for (int i = 0; i < n; ++i) { - for (int j = 0; j < m; ++j) { - cin >> mat[i][j]; - M[mat[i][j]] = k++; + int k = 0; + map<string,int> M; + for (int i = 0; i < n; ++i) { + for (int j = 0; j < m; ++j) { + cin >> mat[i][j]; + M[mat[i][j]] = k++; + } + cin >> c[i]; } - cin >> c[i]; - } - - for (int j = 0; j < m; ++j) - cin >> r[j]; - - map<string,int> ans; - for (int i = 0; i < M.size(); ++i) { - string found = "nono"; - - for (int j = 0; j < n; ++j) { - map<string,int> S; - for (int k = 0; k < m; ++k) - S[mat[j][k]]++; - if (S.find("aaa") != S.end()) - S.erase("aaa"); + for (int j = 0; j < m; ++j) + cin >> r[j]; - if (S.size() == 1) { - found = S.begin()->fi; - ans[S.begin()->fi] = c[j] / S.begin()->se; - break; - } - } + map<string,int> ans; + for (int i = 0; i < M.size(); ++i) { + string found = "nono"; - if (found == "nono") { - for (int j = 0; j < m; ++j) { - map<string,int> S; - for (int k = 0; k < n; ++k) - S[mat[k][j]]++; + for (int j = 0; j < n; ++j) { + map<string,int> S; + for (int k = 0; k < m; ++k) + S[mat[j][k]]++; - if (S.find("aaa") != S.end()) - S.erase("aaa"); + if (S.find("aaa") != S.end()) + S.erase("aaa"); - if (S.size() == 1) { - found = S.begin()->fi; - ans[S.begin()->fi] = r[j] / S.begin()->se; - break; + if (S.size() == 1) { + found = S.begin()->fi; + ans[S.begin()->fi] = c[j] / S.begin()->se; + break; + } } - } - } - for (int j = 0; j < n; ++j) - for (int k = 0; k < m; ++k) - if (mat[j][k] == found) { - r[k] -= ans[found]; - c[j] -= ans[found]; - mat[j][k] = "aaa"; + if (found == "nono") { + for (int j = 0; j < m; ++j) { + map<string,int> S; + for (int k = 0; k < n; ++k) + S[mat[k][j]]++; + + if (S.find("aaa") != S.end()) + S.erase("aaa"); + + if (S.size() == 1) { + found = S.begin()->fi; + ans[S.begin()->fi] = r[j] / S.begin()->se; + break; + } + } } - } - for (auto i : ans) - cout << i.fi << " " << i.se << ende; - return 0; + for (int j = 0; j < n; ++j) + for (int k = 0; k < m; ++k) + if (mat[j][k] == found) { + r[k] -= ans[found]; + c[j] -= ans[found]; + mat[j][k] = "aaa"; + } + } + + for (auto i : ans) + cout << i.fi << " " << i.se << ende; + return 0; } diff --git a/contests/SBC15/E.cpp b/contests/SBC15/E.cpp index 6a3d117702ae386693a5eb275dad601415adde22..18ad21f8e15a1d237940cedc45a0fad46d41561b 100644 --- a/contests/SBC15/E.cpp +++ b/contests/SBC15/E.cpp @@ -22,33 +22,33 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - ll n, b; cin >> n >> b; - if (b <= n) - return cout << 1 << " " << b, 0; - - auto f = [&](ll x) { - ll sum = ((n - 1LL) * n); - return sum - (x * (x+1LL)); - }; - - ll k = n - 1; - for (ll bb = n / 2; bb >= 1; bb /= 2) - while (k - bb >= 0 && n + f(k - bb) <= b) - k -= bb; - - ll base = n + f(k); - if (base + k <= b) - base += k; - - ll kk = 0; - for (ll bb = n / 2; bb >= 1; bb /= 2) - while (base + kk + bb < ) - - cout << f(6) << ende; - cout << k << ende; - cout << base << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + ll n, b; cin >> n >> b; + if (b <= n) + return cout << 1 << " " << b, 0; + + auto f = [&](ll x) { + ll sum = ((n - 1LL) * n); + return sum - (x * (x+1LL)); + }; + + ll k = n - 1; + for (ll bb = n / 2; bb >= 1; bb /= 2) + while (k - bb >= 0 && n + f(k - bb) <= b) + k -= bb; + + ll base = n + f(k); + if (base + k <= b) + base += k; + + ll kk = 0; + for (ll bb = n / 2; bb >= 1; bb /= 2) + while (base + kk + bb < ) + + cout << f(6) << ende; + cout << k << ende; + cout << base << ende; + return 0; } diff --git a/contests/SBC15/F.cpp b/contests/SBC15/F.cpp index e920a79a8bc8d8ce1e90a0b0c9fd4a584458f430..074e009e7062bb3eadb483eb2c95a1bf59aa5d8d 100644 --- a/contests/SBC15/F.cpp +++ b/contests/SBC15/F.cpp @@ -22,22 +22,22 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n; cin >> n; - vector<int> fat(10); - fat[0] = 1; - for (int i = 1; i < 10; ++i) - fat[i] = fat[i-1] * i; - - int ans = 0; - for (int i = 9; i >= 1; --i) - while (n - fat[i] >= 0) { - n -= fat[i]; - ans++; - } - - cout << ans << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int n; cin >> n; + vector<int> fat(10); + fat[0] = 1; + for (int i = 1; i < 10; ++i) + fat[i] = fat[i-1] * i; + + int ans = 0; + for (int i = 9; i >= 1; --i) + while (n - fat[i] >= 0) { + n -= fat[i]; + ans++; + } + + cout << ans << ende; + return 0; } diff --git a/contests/SBC15/J.cpp b/contests/SBC15/J.cpp index f109992dda14b8089a8afbd6ece92561e3b7f6c4..f97b912eb946e2d9e372b8ba03b049eaa5f3af47 100644 --- a/contests/SBC15/J.cpp +++ b/contests/SBC15/J.cpp @@ -22,21 +22,21 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int j, r; cin >> j >> r; - vector<int> p(j, 0); - for (int i = 0; i < j*r; ++i) { - int x; cin >> x; - p[i%j] += x; - } - - int ans = 0; - for (int i = 0; i < j; ++i) - if (p[ans] <= p[i]) - ans = i; - - cout << ans + 1 << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int j, r; cin >> j >> r; + vector<int> p(j, 0); + for (int i = 0; i < j*r; ++i) { + int x; cin >> x; + p[i%j] += x; + } + + int ans = 0; + for (int i = 0; i < j; ++i) + if (p[ans] <= p[i]) + ans = i; + + cout << ans + 1 << ende; + return 0; } diff --git a/contests/SBC15/K.cpp b/contests/SBC15/K.cpp index 7d255179eae15948bbc1efea5c399f01849dcb49..72a0246c5896701219378d7c968c36e4013d6a76 100644 --- a/contests/SBC15/K.cpp +++ b/contests/SBC15/K.cpp @@ -28,42 +28,42 @@ int v[MAX]; ii dp[MAX][MAX]; ii operator+(const ii &a, const ii &b) { - return {a.fi + b.fi, a.se + b.se}; + return {a.fi + b.fi, a.se + b.se}; } ii solve(int l, int r) { - if (l > r) return ii(0, 0); - if (l == r) return ii(v[l], 1); - - if (dp[l][r].fi != -1) - return dp[l][r]; - - ii op = {-inf, -inf}; - if (s[l] == s[r]) - op = solve(l + 1, r - 1) + ii(v[l] + v[r], 2); - - return dp[l][r] = max({ - op, - solve(l + 1, r - 1), - solve(l + 1, r), - solve(l, r - 1) - }); + if (l > r) return ii(0, 0); + if (l == r) return ii(v[l], 1); + + if (dp[l][r].fi != -1) + return dp[l][r]; + + ii op = {-inf, -inf}; + if (s[l] == s[r]) + op = solve(l + 1, r - 1) + ii(v[l] + v[r], 2); + + return dp[l][r] = max({ + op, + solve(l + 1, r - 1), + solve(l + 1, r), + solve(l, r - 1) + }); } int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - cin >> s >> n; - for (int i = 0; i < n; ++i) { - int x; cin >> x; - v[x - 1] = 1; - } + cin >> s >> n; + for (int i = 0; i < n; ++i) { + int x; cin >> x; + v[x - 1] = 1; + } - for (int i = 0; i < MAX; ++i) - for (int j = 0; j < MAX; ++j) - dp[i][j] = {-1, -1}; + for (int i = 0; i < MAX; ++i) + for (int j = 0; j < MAX; ++j) + dp[i][j] = {-1, -1}; - cout << solve(0, s.size() - 1).se << ende; - return 0; + cout << solve(0, s.size() - 1).se << ende; + return 0; } diff --git a/contests/SBC16/A.cpp b/contests/SBC16/A.cpp index ef761a5a1b58c06f9534eb6fbc20562c1544b385..49226cf9b852cc13c114bd7a5c26dd40af8d7025 100644 --- a/contests/SBC16/A.cpp +++ b/contests/SBC16/A.cpp @@ -22,28 +22,28 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - vector<int> v(3); - for (auto &i: v) cin >> i; - - bool poss = false; - for (int i = 1; i < 8; ++i) { - for (int j = 0; j < 8; ++j) { - int sum = 0; - for (int k = 0; k < 3; ++k) { - if (i & (1 << k)) { - if (j & (1 << k)) sum += v[k]; - else sum -= v[k]; + ios::sync_with_stdio(0); + cin.tie(0); + + vector<int> v(3); + for (auto &i: v) cin >> i; + + bool poss = false; + for (int i = 1; i < 8; ++i) { + for (int j = 0; j < 8; ++j) { + int sum = 0; + for (int k = 0; k < 3; ++k) { + if (i & (1 << k)) { + if (j & (1 << k)) sum += v[k]; + else sum -= v[k]; + } + } + + if (sum == 0) poss = true; } - } - - if (sum == 0) poss = true; } - } - if (poss) cout << "S" << ende; - else cout << "N" << ende; - return 0; + if (poss) cout << "S" << ende; + else cout << "N" << ende; + return 0; } diff --git a/contests/SBC16/H.cpp b/contests/SBC16/H.cpp index 9a514f49813ae3ecbc239f0702c64ebf85fc1f43..5ca985a5bfd926356552ac93dc025dbe1a1eb641 100644 --- a/contests/SBC16/H.cpp +++ b/contests/SBC16/H.cpp @@ -22,20 +22,20 @@ using ll = long long; using ii = pair<int,int>; bool vowel(char x) { - return (x == 'a') || (x == 'e') || (x == 'i') || (x == 'o') || (x == 'u'); + return (x == 'a') || (x == 'e') || (x == 'i') || (x == 'o') || (x == 'u'); } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - string s; cin >> s; - string t, w; - for (auto i : s) if (vowel(i)) t.pb(i); - w = t; - reverse(all(t)); - if (w == t) cout << "S" << ende; - else cout << "N" << ende; - - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + string s; cin >> s; + string t, w; + for (auto i : s) if (vowel(i)) t.pb(i); + w = t; + reverse(all(t)); + if (w == t) cout << "S" << ende; + else cout << "N" << ende; + + return 0; } diff --git a/contests/SBC17/A.cpp b/contests/SBC17/A.cpp index a4c783a82b69a9c11dea21b883635b7a327d42f3..7c165091fc6171396ce98da9e7191036c6c730bc 100644 --- a/contests/SBC17/A.cpp +++ b/contests/SBC17/A.cpp @@ -24,32 +24,32 @@ typedef long long ll; typedef pair<int,int> ii; typedef struct elem { - int freq[9]; - - elem() { - for (int i = 0; i < 9; ++i) freq[i] = 0; - } - - elem(int x) { - for (int i = 0; i < 9; ++i) freq[i] = 0; - freq[x] = 1; - } - - elem operator+(const elem &a) { - elem e; - for (int i = 0; i < 9; ++i) - e.freq[i] = a.freq[i] + freq[i]; - return e; - } - - void change(int x) { - vector<int> aux(9, 0); - for (int i = 0; i < 9; ++i) - aux[(i + x) % 9] += freq[i]; - - for (int i = 0; i < 9; ++i) - freq[i] = aux[i]; - } + int freq[9]; + + elem() { + for (int i = 0; i < 9; ++i) freq[i] = 0; + } + + elem(int x) { + for (int i = 0; i < 9; ++i) freq[i] = 0; + freq[x] = 1; + } + + elem operator+(const elem &a) { + elem e; + for (int i = 0; i < 9; ++i) + e.freq[i] = a.freq[i] + freq[i]; + return e; + } + + void change(int x) { + vector<int> aux(9, 0); + for (int i = 0; i < 9; ++i) + aux[(i + x) % 9] += freq[i]; + + for (int i = 0; i < 9; ++i) + freq[i] = aux[i]; + } } elem; @@ -62,99 +62,99 @@ int lazy[4 * MAX]; #define right(x) ((x << 1) + 1) void build(int node = 1, int a = 0, int b = N - 1) { - if (a > b) - return; + if (a > b) + return; - if (a == b) { - tree[node] = v[a]; - return; - } + if (a == b) { + tree[node] = v[a]; + return; + } - build(left(node), a, (a + b) / 2); - build(right(node), (a + b) / 2 + 1, b); - tree[node] = tree[node * 2] + tree[node * 2 + 1]; + build(left(node), a, (a + b) / 2); + build(right(node), (a + b) / 2 + 1, b); + tree[node] = tree[node * 2] + tree[node * 2 + 1]; } void push(int node, int a, int b, int val) { - tree[node].change(val); + tree[node].change(val); - if (a != b) { - lazy[left(node)] += val; - lazy[right(node)] += val; - } + if (a != b) { + lazy[left(node)] += val; + lazy[right(node)] += val; + } - lazy[node] = 0; + lazy[node] = 0; } void update(int i, int j, int val, int node = 1, int a = 0, int b = N - 1) { - if (lazy[node] != 0) - push(node, a, b, lazy[node]); + if (lazy[node] != 0) + push(node, a, b, lazy[node]); - if (a > b || a > j || b < i) - return; + if (a > b || a > j || b < i) + return; - if (i <= a && b <= j) { - push(node, a, b, val); - return; - } + if (i <= a && b <= j) { + push(node, a, b, val); + return; + } - update(i, j, val, left(node), a, (a + b) / 2); - update(i, j, val, right(node), (a + b) / 2 + 1, b); - tree[node] = tree[node * 2] + tree[node * 2 + 1]; + update(i, j, val, left(node), a, (a + b) / 2); + update(i, j, val, right(node), (a + b) / 2 + 1, b); + tree[node] = tree[node * 2] + tree[node * 2 + 1]; } elem query(int i, int j, int node = 1, int a = 0, int b = N - 1) { - if (a > b || a > j || b < i) - return elem(); + if (a > b || a > j || b < i) + return elem(); - if (lazy[node]) - push(node, a, b, lazy[node]); + if (lazy[node]) + push(node, a, b, lazy[node]); - if (a >= i && b <= j) - return tree[node]; + if (a >= i && b <= j) + return tree[node]; - elem q1 = query(i, j, left(node), a, (a + b) / 2); - elem q2 = query(i, j, right(node), (a + b) / 2 + 1, b); - return q1 + q2; + elem q1 = query(i, j, left(node), a, (a + b) / 2); + elem q2 = query(i, j, right(node), (a + b) / 2 + 1, b); + return q1 + q2; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int n, q; cin >> n >> q; - for (int i = 0; i < n; ++i) - v[i] = elem(1); + int n, q; cin >> n >> q; + for (int i = 0; i < n; ++i) + v[i] = elem(1); - N = n; - build(); + N = n; + build(); - for (int i = 0; i < q; ++i) { - int a, b; cin >> a >> b; - elem e = query(a, b); + for (int i = 0; i < q; ++i) { + int a, b; cin >> a >> b; + elem e = query(a, b); - int grt = 0; - for (int i = 1; i < 9; ++i) - if (e.freq[i] >= e.freq[grt]) - grt = i; + int grt = 0; + for (int i = 1; i < 9; ++i) + if (e.freq[i] >= e.freq[grt]) + grt = i; - update(a, b, grt); - } + update(a, b, grt); + } - for (int i = 0; i < n; ++i) { - elem e = query(i, i); + for (int i = 0; i < n; ++i) { + elem e = query(i, i); - int grt = 0; - for (int i = 0; i < 9; ++i) - if (e.freq[i] >= e.freq[grt]) - grt = i; + int grt = 0; + for (int i = 0; i < 9; ++i) + if (e.freq[i] >= e.freq[grt]) + grt = i; - cout << grt << ende; - } + cout << grt << ende; + } - return 0; + return 0; } diff --git a/contests/SBC17/B.cpp b/contests/SBC17/B.cpp index 23353828d830b36648dd7f2b778727e75161922c..6373cb72f7ce8fcad0ed0bbd20258d65f4c47db8 100644 --- a/contests/SBC17/B.cpp +++ b/contests/SBC17/B.cpp @@ -24,35 +24,35 @@ typedef pair<int,int> ii; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - ll n, t, a0, x, y; - cin >> n >> t >> a0 >> x >> y; + ll n, t, a0, x, y; + cin >> n >> t >> a0 >> x >> y; - vector<ll> tor(t); - for (auto &i : tor) cin >> i; + vector<ll> tor(t); + for (auto &i : tor) cin >> i; - auto next = [&]() { - ll xxor = 0; - for (auto i : tor) - xxor ^= !!(a0 & (1 << i)); - return a0 = ((a0 >> 1) | (xxor << (n - 1))); - }; + auto next = [&]() { + ll xxor = 0; + for (auto i : tor) + xxor ^= !!(a0 & (1 << i)); + return a0 = ((a0 >> 1) | (xxor << (n - 1))); + }; - vector<ll> idx(x + 1, 0); - idx[0] = 1; + vector<ll> idx(x + 1, 0); + idx[0] = 1; - ll acc = a0 % x; - for (ll i = 2; ; ++i) { - if (idx[acc] && i - idx[acc] >= y) - return cout << idx[acc] - 1 << " " << i - 2 << ende, 0; - else if (!idx[acc]) - idx[acc] = i; + ll acc = a0 % x; + for (ll i = 2; ; ++i) { + if (idx[acc] && i - idx[acc] >= y) + return cout << idx[acc] - 1 << " " << i - 2 << ende, 0; + else if (!idx[acc]) + idx[acc] = i; - acc = (acc + next()) % x; - } + acc = (acc + next()) % x; + } - return 0; + return 0; } diff --git a/contests/SBC17/C.cpp b/contests/SBC17/C.cpp index ccd9f72a749d734e801a881cf6f94cc6d6b56571..6fb74d88624a58cd0582a5287c8a74c1326cf7fb 100644 --- a/contests/SBC17/C.cpp +++ b/contests/SBC17/C.cpp @@ -23,31 +23,31 @@ typedef long long ll; typedef pair<int,int> ii; ll lcm(ll a, ll b) { - return (a * b) / __gcd(a, b); + return (a * b) / __gcd(a, b); } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - ll n, l; cin >> n >> l; - ll acc = 1; - for (int i = 0; i < n; ++i) { - ll x; cin >> x; - acc = lcm(acc, x); - } - - ll ans = -1; - ll grt = -1; - for (int i = 1; i <= l; ++i) { - ll lc = lcm(acc, i); - if (lc > grt && lc <= l) { - grt = lc; - ans = i; + ios::sync_with_stdio(0); + cin.tie(0); + + ll n, l; cin >> n >> l; + ll acc = 1; + for (int i = 0; i < n; ++i) { + ll x; cin >> x; + acc = lcm(acc, x); } - } - cout << ans << ende; - return 0; + ll ans = -1; + ll grt = -1; + for (int i = 1; i <= l; ++i) { + ll lc = lcm(acc, i); + if (lc > grt && lc <= l) { + grt = lc; + ans = i; + } + } + + cout << ans << ende; + return 0; } diff --git a/contests/SBC17/D.cpp b/contests/SBC17/D.cpp index a5645138916aaf03ebea613f810d92f787d69c27..5eb985afa340f06b7b48ca7cb173562058b56186 100644 --- a/contests/SBC17/D.cpp +++ b/contests/SBC17/D.cpp @@ -24,34 +24,34 @@ typedef long long ll; typedef pair<int,int> ii; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - ll n; cin >> n; - vector<ll> f; - vector<ll> fat; + ll n; cin >> n; + vector<ll> f; + vector<ll> fat; - ll acc = 1; - fat.pb(1); - for (ll i = 1; i <= 40; ++i) { - acc *= i; - fat.pb(acc); - } + ll acc = 1; + fat.pb(1); + for (ll i = 1; i <= 40; ++i) { + acc *= i; + fat.pb(acc); + } - if (n % 2 == 0) f.pb(2); - while (n % 2 == 0) n /= 2; + if (n % 2 == 0) f.pb(2); + while (n % 2 == 0) n /= 2; - for (ll i = 3; i*i <= n; i+=2) { - if (n % i == 0) f.pb(i); - while (n % i == 0) n /= i; - } + for (ll i = 3; i*i <= n; i+=2) { + if (n % i == 0) f.pb(i); + while (n % i == 0) n /= i; + } - if (n > 2) f.pb(n); + if (n > 2) f.pb(n); - ll ans = 0; - for (ll i = 2; i <= f.sz; ++i) - ans += fat[f.sz] / (fat[f.sz - i] * fat[i]); - cout << ans << ende; + ll ans = 0; + for (ll i = 2; i <= f.sz; ++i) + ans += fat[f.sz] / (fat[f.sz - i] * fat[i]); + cout << ans << ende; - return 0; + return 0; } diff --git a/contests/SBC17/E.cpp b/contests/SBC17/E.cpp index da220128bcd6484e1fae71c063dfea1de5c0cc37..4bfbf0b55ed165cf88e0b430fdb47ac333541108 100644 --- a/contests/SBC17/E.cpp +++ b/contests/SBC17/E.cpp @@ -24,37 +24,37 @@ typedef long long ll; typedef pair<int,int> ii; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - vector<string> notas = {"do", "do#", "re", "re#", "mi", "fa", "fa#", "sol", "sol#", "la", "la#", "si"}; - vector<int> count(notas.sz); - vector<int> diff = {2, 2, 1, 2, 2, 2, 1}; - vector<vector<int>> v(notas.sz, vector<int>(notas.sz, 0)); - - for (int i = 0; i < v.sz; ++i) { - int beg = i; - for (int j = 0; j < diff.sz; ++j) { - v[i][beg] = 1; - beg = (beg + diff[j]) % 12; + ios::sync_with_stdio(0); + cin.tie(0); + + vector<string> notas = {"do", "do#", "re", "re#", "mi", "fa", "fa#", "sol", "sol#", "la", "la#", "si"}; + vector<int> count(notas.sz); + vector<int> diff = {2, 2, 1, 2, 2, 2, 1}; + vector<vector<int>> v(notas.sz, vector<int>(notas.sz, 0)); + + for (int i = 0; i < v.sz; ++i) { + int beg = i; + for (int j = 0; j < diff.sz; ++j) { + v[i][beg] = 1; + beg = (beg + diff[j]) % 12; + } } - } - - int n; cin >> n; - for (int i = 0; i < n; ++i) { - int x; cin >> x; x--; - count[x % 12]++; - } - - for (int i = 0; i < 12; ++i) { - bool poss = true; - for (int j = 0; j < 12; ++j) - if (count[j] and !v[i][j]) - poss = false; - if (poss) - return cout << notas[i] << ende, 0; - } - cout << "desafinado" << ende; - - return 0; + + int n; cin >> n; + for (int i = 0; i < n; ++i) { + int x; cin >> x; x--; + count[x % 12]++; + } + + for (int i = 0; i < 12; ++i) { + bool poss = true; + for (int j = 0; j < 12; ++j) + if (count[j] and !v[i][j]) + poss = false; + if (poss) + return cout << notas[i] << ende, 0; + } + cout << "desafinado" << ende; + + return 0; } diff --git a/contests/SBC17/F.cpp b/contests/SBC17/F.cpp index e52ecd1043eda718c187adcf932c85bd420d1e3d..6ef131c77655466603ba6fb94a2388f689b85cb8 100644 --- a/contests/SBC17/F.cpp +++ b/contests/SBC17/F.cpp @@ -24,17 +24,17 @@ typedef long long ll; typedef pair<int,int> ii; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int n, k; cin >> n >> k; - vector<int> v(n); - for (auto &i : v) cin >> i; - sort(rall(v)); + int n, k; cin >> n >> k; + vector<int> v(n); + for (auto &i : v) cin >> i; + sort(rall(v)); - int ans = k; - while (v[ans] == v[ans-1] and ans < n) ans++; - cout << ans << ende; + int ans = k; + while (v[ans] == v[ans-1] and ans < n) ans++; + cout << ans << ende; - return 0; + return 0; } diff --git a/contests/SBC17/G.cpp b/contests/SBC17/G.cpp index 9282ec08c438dd1adb08aed051171b452648bec7..40f40545b0508cc3a9ea66efab183e472f0339c4 100644 --- a/contests/SBC17/G.cpp +++ b/contests/SBC17/G.cpp @@ -26,24 +26,24 @@ typedef pair<int,int> ii; ll dp[51][MAX]; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int t, m, n; cin >> t >> m >> n; + int t, m, n; cin >> t >> m >> n; - for (int i = m; i <= n; ++i) - dp[1][i] = 1; + for (int i = m; i <= n; ++i) + dp[1][i] = 1; - for (int i = 2; i <= t; ++i) - for (int j = m; j <= n; ++j) - if (j == m) dp[i][j] = dp[i-1][j+1]; - else if (j == n) dp[i][j] = dp[i-1][j-1]; - else dp[i][j] = (dp[i-1][j-1] + dp[i-1][j+1]) % MOD; + for (int i = 2; i <= t; ++i) + for (int j = m; j <= n; ++j) + if (j == m) dp[i][j] = dp[i-1][j+1]; + else if (j == n) dp[i][j] = dp[i-1][j-1]; + else dp[i][j] = (dp[i-1][j-1] + dp[i-1][j+1]) % MOD; - ll ans = 0; - for (int i = m; i <= n; ++i) - ans = (ans + dp[t][i]) % MOD; + ll ans = 0; + for (int i = m; i <= n; ++i) + ans = (ans + dp[t][i]) % MOD; - cout << ans << ende; - return 0; + cout << ans << ende; + return 0; } diff --git a/contests/SBC17/H.cpp b/contests/SBC17/H.cpp index 654d0bf8008c0132332f187130c50d813e465c9f..151c9cc2db868990917fe311024833ea40461b40 100644 --- a/contests/SBC17/H.cpp +++ b/contests/SBC17/H.cpp @@ -27,27 +27,27 @@ typedef pair<double,double> dd; int dp[MAX][MAX]; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n; cin >> n; - double xa, xb; cin >> xa >> xb; - - vector<dd> pp; - pp.pb(dd(-1, -1)); - for (int i = 0; i < n; ++i) { - double x, y; cin >> x >> y; - pp.pb(dd(asin(y / hypot(xa - x, y)), asin(y / hypot(xb - x, y)))); - } - - sort(all(pp)); - for (int i = n + 1; i >= 1; --i) - for (int j = 0; j <= n; ++j) - if (j == 0 || (pp[i].fi > pp[j].fi && pp[i].se > pp[j].se)) - dp[i][j] = max(dp[i+1][i] + 1, dp[i+1][j]); - else - dp[i][j] = dp[i+1][j]; - - cout << dp[1][0] << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int n; cin >> n; + double xa, xb; cin >> xa >> xb; + + vector<dd> pp; + pp.pb(dd(-1, -1)); + for (int i = 0; i < n; ++i) { + double x, y; cin >> x >> y; + pp.pb(dd(asin(y / hypot(xa - x, y)), asin(y / hypot(xb - x, y)))); + } + + sort(all(pp)); + for (int i = n + 1; i >= 1; --i) + for (int j = 0; j <= n; ++j) + if (j == 0 || (pp[i].fi > pp[j].fi && pp[i].se > pp[j].se)) + dp[i][j] = max(dp[i+1][i] + 1, dp[i+1][j]); + else + dp[i][j] = dp[i+1][j]; + + cout << dp[1][0] << ende; + return 0; } diff --git a/contests/SBC17/I.cpp b/contests/SBC17/I.cpp index 0f7b97d237a864a248490e77328dc74b1e0d23f5..74267a2b31899890ade0a59cf13e829a9e96a688 100644 --- a/contests/SBC17/I.cpp +++ b/contests/SBC17/I.cpp @@ -30,37 +30,37 @@ bool cont[MAX]; vector<ii> graph[MAX]; int dfs(int x) { - cont[x] = true; + cont[x] = true; - for (auto i : graph[x]) { - if (!cont[i.fi]) { - E[x] += dfs(i.fi); - ans += 2 * i.se * ((E[i.fi] - 1) / C + 1); + for (auto i : graph[x]) { + if (!cont[i.fi]) { + E[x] += dfs(i.fi); + ans += 2 * i.se * ((E[i.fi] - 1) / C + 1); + } } - } - return E[x]; + return E[x]; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n; cin >> n >> C; - for (int i = 0; i < n; ++i) - cin >> E[i]; - - for (int i = 0; i < n - 1; ++i) { - int a, b, c; cin >> a >> b >> c; - a--, b--; - graph[a].pb(ii(b, c)); - graph[b].pb(ii(a, c)); - } + ios::sync_with_stdio(0); + cin.tie(0); + + int n; cin >> n >> C; + for (int i = 0; i < n; ++i) + cin >> E[i]; + + for (int i = 0; i < n - 1; ++i) { + int a, b, c; cin >> a >> b >> c; + a--, b--; + graph[a].pb(ii(b, c)); + graph[b].pb(ii(a, c)); + } - dfs(0); - cout << ans << ende; + dfs(0); + cout << ans << ende; - return 0; + return 0; } diff --git a/contests/SBC17/J.cpp b/contests/SBC17/J.cpp index f9b9b64d277c18de88494f41701e1c9039c2f358..455eee47308830310ce72436d90ca40afff514dc 100644 --- a/contests/SBC17/J.cpp +++ b/contests/SBC17/J.cpp @@ -24,13 +24,13 @@ typedef long long ll; typedef pair<int,int> ii; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - ll num = 0; - string s; cin >> s; - for (auto i : s) num += i - '0'; - cout << num % 3 << ende; + ll num = 0; + string s; cin >> s; + for (auto i : s) num += i - '0'; + cout << num % 3 << ende; - return 0; + return 0; } diff --git a/contests/SBC17/K.cpp b/contests/SBC17/K.cpp index 1215b514afdaf04de396ea7273b0073b74dfea2e..2b017612931cd6b7c51db90b3f5e969d9bc447c2 100644 --- a/contests/SBC17/K.cpp +++ b/contests/SBC17/K.cpp @@ -26,77 +26,77 @@ typedef pair<int,int> ii; template <typename T> struct matrix { - T m[K][K]; + T m[K][K]; - matrix operator*(matrix a) { - matrix aux; + matrix operator*(matrix a) { + matrix aux; - for (int i = 0; i < K; i++) - for (int j = 0; j < K; j++) { - ll sum = 0; + for (int i = 0; i < K; i++) + for (int j = 0; j < K; j++) { + ll sum = 0; - for (int k = 0; k < K; k++) - sum += (m[i][k] * a[k][j]) % MOD; + for (int k = 0; k < K; k++) + sum += (m[i][k] * a[k][j]) % MOD; - aux[i][j] = sum % MOD; - } - - return aux; - } + aux[i][j] = sum % MOD; + } - T *operator[](int i) { - return m[i]; - } + return aux; + } - void clear() { - mset(m, 0); - } + T *operator[](int i) { + return m[i]; + } + + void clear() { + mset(m, 0); + } }; matrix<ll> matrix_pow(matrix<ll> in, ll n) { - matrix<ll> ans, b = in; + matrix<ll> ans, b = in; - ans.clear(); - for (int i = 0; i < K; ++i) - ans[i][i] = 1; + ans.clear(); + for (int i = 0; i < K; ++i) + ans[i][i] = 1; - while (n) { - if (n & 1) - ans = ans * b; + while (n) { + if (n & 1) + ans = ans * b; - n >>= 1; - b = b * b; - } + n >>= 1; + b = b * b; + } - return ans; + return ans; } matrix<ll> solve(ll x, ll y, ll n) { - matrix<ll> in; + matrix<ll> in; - in[0][0] = x % MOD; - in[0][1] = y % MOD; - in[1][0] = 1; - in[1][1] = 0; + in[0][0] = x % MOD; + in[0][1] = y % MOD; + in[1][0] = 1; + in[1][1] = 0; - return matrix_pow(in, n); + return matrix_pow(in, n); } int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); + + ll a, b, n, k; cin >> a >> b >> n >> k; - ll a, b, n, k; cin >> a >> b >> n >> k; + matrix<ll> ans = solve(2 * a, (b - a * a) + MOD, n - 1); + ll res = (ans[0][0] * 2 * a + ans[0][1] * 2) % MOD; - matrix<ll> ans = solve(2 * a, (b - a * a) + MOD, n - 1); - ll res = (ans[0][0] * 2 * a + ans[0][1] * 2) % MOD; + if (a * a > b || (a * a < b && n % 2 == 0)) + res = ((res - 1) + MOD) % MOD; - if (a * a > b || (a * a < b && n % 2 == 0)) - res = ((res - 1) + MOD) % MOD; + for (int i = 0; i < k-1; ++i) + res /= 10; - for (int i = 0; i < k-1; ++i) - res /= 10; - - cout << res % 10 << ende; - return 0; + cout << res % 10 << ende; + return 0; } diff --git a/contests/SBC17/L.cpp b/contests/SBC17/L.cpp index c2e782b3b353ec66845ffec69969f85661eabb6f..ffee98484073340435ba139fec69b73ce69d59ae 100644 --- a/contests/SBC17/L.cpp +++ b/contests/SBC17/L.cpp @@ -22,134 +22,134 @@ typedef long long ll; typedef pair<int,int> ii; struct comp { - float r, i; + float r, i; - comp() : r(0), i(0) {} - comp(float r, float i) : r(r), i(i) {} + comp() : r(0), i(0) {} + comp(float r, float i) : r(r), i(i) {} - comp operator+(comp b) { - return comp(r + b.r, i + b.i); - } + comp operator+(comp b) { + return comp(r + b.r, i + b.i); + } - comp operator-(comp b) { - return comp(r - b.r, i - b.i); - } + comp operator-(comp b) { + return comp(r - b.r, i - b.i); + } - comp operator*(comp b) { - return comp(r * b.r - i * b.i, r * b.i + i * b.r); - } + comp operator*(comp b) { + return comp(r * b.r - i * b.i, r * b.i + i * b.r); + } - comp operator/(comp b) { - float div = (b.r * b.r) + (b.i * b.i); - return comp((r * b.r + i * b.i) / div, (i * b.r - r * b.i) / div); - } + comp operator/(comp b) { + float div = (b.r * b.r) + (b.i * b.i); + return comp((r * b.r + i * b.i) / div, (i * b.r - r * b.i) / div); + } }; inline comp conj(comp a) { - return comp(a.r, -a.i); + return comp(a.r, -a.i); } vector<int> rev = {0, 1}; vector<comp> roots = {{0, 0}, {1, 0}}; void init(int nbase) { - rev.resize(1 << nbase); - roots.resize(1 << nbase); + rev.resize(1 << nbase); + roots.resize(1 << nbase); - for (int i = 0; i < (1 << nbase); ++i) - rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (nbase - 1)); + for (int i = 0; i < (1 << nbase); ++i) + rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (nbase - 1)); - for (int base = 1; base < nbase; ++base) { - float angle = 2 * M_PI / (1 << (base + 1)); + for (int base = 1; base < nbase; ++base) { + float angle = 2 * M_PI / (1 << (base + 1)); - for (int i = 1 << (base - 1); i < (1 << base); ++i) { - float angle_i = angle * (2 * i + 1 - (1 << base)); + for (int i = 1 << (base - 1); i < (1 << base); ++i) { + float angle_i = angle * (2 * i + 1 - (1 << base)); - roots[i << 1] = roots[i]; - roots[(i << 1) + 1] = comp(cos(angle_i), sin(angle_i)); + roots[i << 1] = roots[i]; + roots[(i << 1) + 1] = comp(cos(angle_i), sin(angle_i)); + } } - } } void fft(vector<comp> &a) { - int n = a.size(); + int n = a.size(); - for (int i = 0; i < n; ++i) - if (i < rev[i]) - swap(a[i], a[rev[i]]); + for (int i = 0; i < n; ++i) + if (i < rev[i]) + swap(a[i], a[rev[i]]); - for (int s = 1; s < n; s <<= 1) { - for (int k = 0; k < n; k += (s << 1)) { - for (int j = 0; j < s; ++j) { - comp z = a[k + j + s] * roots[j + s]; + for (int s = 1; s < n; s <<= 1) { + for (int k = 0; k < n; k += (s << 1)) { + for (int j = 0; j < s; ++j) { + comp z = a[k + j + s] * roots[j + s]; - a[k + j + s] = a[k + j] - z; - a[k + j] = a[k + j] + z; - } + a[k + j + s] = a[k + j] - z; + a[k + j] = a[k + j] + z; + } + } } - } } vector<int> multiply(vector<int> &a, vector<int> &b) { - int nbase, need = a.size() + b.size() + 1; + int nbase, need = a.size() + b.size() + 1; - for (nbase = 0; (1 << nbase) < need; ++nbase); - init(nbase); + for (nbase = 0; (1 << nbase) < need; ++nbase); + init(nbase); - int size = 1 << nbase; - vector<comp> fa(size); + int size = 1 << nbase; + vector<comp> fa(size); - for (int i = 0; i < size; ++i) { - int x = (i < a.size() ? a[i] : 0); - int y = (i < b.size() ? b[i] : 0); - fa[i] = comp(x, y); - } + for (int i = 0; i < size; ++i) { + int x = (i < a.size() ? a[i] : 0); + int y = (i < b.size() ? b[i] : 0); + fa[i] = comp(x, y); + } - fft(fa); + fft(fa); - comp r(0, -0.25 / size); - for (int i = 0; i <= (size >> 1); ++i) { - int j = (size - i) & (size - 1); - comp z = (fa[j] * fa[j] - conj(fa[i] * fa[i])) * r; + comp r(0, -0.25 / size); + for (int i = 0; i <= (size >> 1); ++i) { + int j = (size - i) & (size - 1); + comp z = (fa[j] * fa[j] - conj(fa[i] * fa[i])) * r; - if (i != j) - fa[j] = (fa[i] * fa[i] - conj(fa[j] * fa[j])) * r; - fa[i] = z; - } + if (i != j) + fa[j] = (fa[i] * fa[i] - conj(fa[j] * fa[j])) * r; + fa[i] = z; + } - fft(fa); + fft(fa); - vector<int> res(need); - for (int i = 0; i < need; ++i) - res[i] = fa[i].r + 0.5; + vector<int> res(need); + for (int i = 0; i < need; ++i) + res[i] = fa[i].r + 0.5; - return res; + return res; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - string s; cin >> s; - int n = s.size(); - - int acc = 0, sum = s[0] - 'a' + 1; - for (int i = 1; i < n; ++i) - sum += s[i] - 'a' + 1; - - vector<int> a(sum + 1), b(sum + 1); - a[0] = b[sum] = 1; - for (int i = 0; i < n; ++i) { - acc += s[i] - 'a' + 1; - a[acc] = b[sum - acc] = 1; - } - - vector<int> c = multiply(a, b); - int ans = 0; - for (int i = sum + 1; i <= 2 * sum; ++i) - if (c[i]) ans++; - - cout << ans << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + string s; cin >> s; + int n = s.size(); + + int acc = 0, sum = s[0] - 'a' + 1; + for (int i = 1; i < n; ++i) + sum += s[i] - 'a' + 1; + + vector<int> a(sum + 1), b(sum + 1); + a[0] = b[sum] = 1; + for (int i = 0; i < n; ++i) { + acc += s[i] - 'a' + 1; + a[acc] = b[sum - acc] = 1; + } + + vector<int> c = multiply(a, b); + int ans = 0; + for (int i = sum + 1; i <= 2 * sum; ++i) + if (c[i]) ans++; + + cout << ans << ende; + return 0; } diff --git a/contests/SBC17/M.cpp b/contests/SBC17/M.cpp index 3cc1ffd1c7ac1332312d2f30adee1acb7f4a53d7..69bad130f70c9fa39bf76926834b8cad913c7a5c 100644 --- a/contests/SBC17/M.cpp +++ b/contests/SBC17/M.cpp @@ -24,15 +24,15 @@ typedef long long ll; typedef pair<int,int> ii; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int a, b, c; cin >> a >> b >> c; + int a, b, c; cin >> a >> b >> c; - int x1 = a*0 + b*2 + c*4; - int x2 = a*2 + b*0 + c*2; - int x3 = a*4 + b*2 + c*0; - cout << min(x1, min(x2, x3)) << ende; + int x1 = a*0 + b*2 + c*4; + int x2 = a*2 + b*0 + c*2; + int x3 = a*4 + b*2 + c*0; + cout << min(x1, min(x2, x3)) << ende; - return 0; + return 0; } diff --git a/contests/SBC18/B.cpp b/contests/SBC18/B.cpp index 75822afcb7db47bcd0f5f82555cd54b2d451003e..0787afdd173bfac0526b0f415ddb0a27ca299939 100644 --- a/contests/SBC18/B.cpp +++ b/contests/SBC18/B.cpp @@ -25,45 +25,45 @@ int foi[500]; int dp[102][102]; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int N = 100; - for (int i = 0; i < N; ++i) { - dp[i][i] = 499; - dp[0][i] = 499; - dp[i][0] = 499; - } + int N = 100; + for (int i = 0; i < N; ++i) { + dp[i][i] = 499; + dp[0][i] = 499; + dp[i][0] = 499; + } + + for (int i = 1; i <= N; ++i) { + for (int j = 1; j <= N; ++j) { + if (i != j) { + mset(foi, 0); + for (int k = 1; k <= i; ++k) + foi[dp[i-k][j]] = 1; + for (int k = 1; k <= j; ++k) + foi[dp[i][j-k]] = 1; + for (int k = 1; k <= min(i, j); ++k) + foi[dp[i-k][j-k]] = 1; - for (int i = 1; i <= N; ++i) { - for (int j = 1; j <= N; ++j) { - if (i != j) { - mset(foi, 0); - for (int k = 1; k <= i; ++k) - foi[dp[i-k][j]] = 1; - for (int k = 1; k <= j; ++k) - foi[dp[i][j-k]] = 1; - for (int k = 1; k <= min(i, j); ++k) - foi[dp[i-k][j-k]] = 1; + for (int k = 0; k <= 500; ++k) + if (!foi[k]) { + dp[i][j] = k; + break; + } + } + } + } - for (int k = 0; k <= 500; ++k) - if (!foi[k]) { - dp[i][j] = k; - break; - } - } + int n; cin >> n; + int ans = 0; + for (int i = 0; i < n; ++i) { + int a, b; cin >> a >> b; + if (a == b) + return cout << 'Y' << ende, 0; + ans ^= dp[a][b]; } - } - - int n; cin >> n; - int ans = 0; - for (int i = 0; i < n; ++i) { - int a, b; cin >> a >> b; - if (a == b) - return cout << 'Y' << ende, 0; - ans ^= dp[a][b]; - } - cout << (ans ? 'Y' : 'N') << ende; - return 0; + cout << (ans ? 'Y' : 'N') << ende; + return 0; } diff --git a/contests/SBC18/C.cpp b/contests/SBC18/C.cpp index 1199b955b2fa640bcc4e9cd40f79bbad18ac55c3..66d3e3018f12d91ad7e3b45c01ca0ebef9625f9a 100644 --- a/contests/SBC18/C.cpp +++ b/contests/SBC18/C.cpp @@ -25,61 +25,61 @@ using ii = pair<int,int>; int tree[MAX]; int query(int idx) { - int sum = 0; - for ( ; idx > 0; idx -= (idx & -idx)) - sum += tree[idx]; - return sum; + int sum = 0; + for ( ; idx > 0; idx -= (idx & -idx)) + sum += tree[idx]; + return sum; } void update(int idx, int val) { - for ( ; idx < MAX; idx += (idx & -idx)) - tree[idx] += val; + for ( ; idx < MAX; idx += (idx & -idx)) + tree[idx] += val; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int x, y; cin >> x >> y; - int h, v; cin >> h >> v; - vector<ii> H(h), V(v); - - for (int i = 0; i < h; ++i) { - int x1, x2; cin >> x1 >> x2; - H[i] = ii(x1, x2); - } - - for (int i = 0; i < v; ++i) { - int y1, y2; cin >> y1 >> y2; - V[i] = ii(y1, y2); - } - - sort(all(H)); - for (int i = 0; i < h; ++i) - H[i].fi = i + 1; - sort(all(H), [](ii a, ii b) { - return a.se < b.se; - }); - - sort(all(V)); - for (int i = 0; i < v; ++i) - V[i].fi = i + 1; - sort(all(V), [](ii a, ii b) { - return a.se < b.se; - }); - - ll ans = (h + 1LL) * (v + 1LL); - for (int i = h - 1; i >= 0; --i) { - ans += query(H[i].fi); - update(H[i].fi, 1); - } - - mset(tree, 0); - for (int i = v - 1; i >= 0; --i) { - ans += query(V[i].fi); - update(V[i].fi, 1); - } - - cout << ans << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int x, y; cin >> x >> y; + int h, v; cin >> h >> v; + vector<ii> H(h), V(v); + + for (int i = 0; i < h; ++i) { + int x1, x2; cin >> x1 >> x2; + H[i] = ii(x1, x2); + } + + for (int i = 0; i < v; ++i) { + int y1, y2; cin >> y1 >> y2; + V[i] = ii(y1, y2); + } + + sort(all(H)); + for (int i = 0; i < h; ++i) + H[i].fi = i + 1; + sort(all(H), [](ii a, ii b) { + return a.se < b.se; + }); + + sort(all(V)); + for (int i = 0; i < v; ++i) + V[i].fi = i + 1; + sort(all(V), [](ii a, ii b) { + return a.se < b.se; + }); + + ll ans = (h + 1LL) * (v + 1LL); + for (int i = h - 1; i >= 0; --i) { + ans += query(H[i].fi); + update(H[i].fi, 1); + } + + mset(tree, 0); + for (int i = v - 1; i >= 0; --i) { + ans += query(V[i].fi); + update(V[i].fi, 1); + } + + cout << ans << ende; + return 0; } diff --git a/contests/SBC18/D.cpp b/contests/SBC18/D.cpp index 7381f967d6234c5c0665bffa93525d5d4f8666fc..e58bc6a017afcec03fb50e35e16e7d3a2f0ffe99 100644 --- a/contests/SBC18/D.cpp +++ b/contests/SBC18/D.cpp @@ -22,16 +22,16 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n; cin >> n; - int ans = 0; - for (int i = 0; i < n; ++i) { - int x; cin >> x; - ans += (x != 1); - } - - cout << ans << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int n; cin >> n; + int ans = 0; + for (int i = 0; i < n; ++i) { + int x; cin >> x; + ans += (x != 1); + } + + cout << ans << ende; + return 0; } diff --git a/contests/SBC18/E.cpp b/contests/SBC18/E.cpp index c22dca27bc406157fa1597b42a4cf9646b0c3841..d375a3edc3fcf4be604bed8c3f52bc0fea08770a 100644 --- a/contests/SBC18/E.cpp +++ b/contests/SBC18/E.cpp @@ -22,23 +22,23 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - string s, t; cin >> s >> t; - int ans = 0; - for (int i = 0; i <= s.size() - t.size(); ++i) { - bool poss = true; - for (int j = 0; j < t.size(); ++j) - if (s[i+j] == t[j]) { - poss = false; - break; - } - - if (poss) - ans++; - } - - cout << ans << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + string s, t; cin >> s >> t; + int ans = 0; + for (int i = 0; i <= s.size() - t.size(); ++i) { + bool poss = true; + for (int j = 0; j < t.size(); ++j) + if (s[i+j] == t[j]) { + poss = false; + break; + } + + if (poss) + ans++; + } + + cout << ans << ende; + return 0; } diff --git a/contests/SBC18/F.cpp b/contests/SBC18/F.cpp index bdfeecebb0b4a33908b1d711c5799d6f8eae4485..350b11f2c64051e8a5c0d087c48bde04e84ab9f0 100644 --- a/contests/SBC18/F.cpp +++ b/contests/SBC18/F.cpp @@ -28,51 +28,51 @@ vector<Show> v; int dp[1010][3010]; int solve(int i, int mask) { - if (i == N) { - if (mask == (1 << S) - 1) - return 0; - return -inf; - } - - if (dp[i][mask] != -1) - return dp[i][mask]; - - int op1 = solve(v[i].nxt, mask | (1 << v[i].s)) + v[i].o; - int op2 = solve(i + 1, mask); - return dp[i][mask] = max(op1, op2); + if (i == N) { + if (mask == (1 << S) - 1) + return 0; + return -inf; + } + + if (dp[i][mask] != -1) + return dp[i][mask]; + + int op1 = solve(v[i].nxt, mask | (1 << v[i].s)) + v[i].o; + int op2 = solve(i + 1, mask); + return dp[i][mask] = max(op1, op2); } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n; cin >> n; - S = n; - for (int i = 0; i < n; ++i) { - int m; cin >> m; - for (int j = 0; j < m; ++j) { - int ii, ff, oo; cin >> ii >> ff >> oo; - v.pb({ii, ff, oo, i, -1}); + ios::sync_with_stdio(0); + cin.tie(0); + + int n; cin >> n; + S = n; + for (int i = 0; i < n; ++i) { + int m; cin >> m; + for (int j = 0; j < m; ++j) { + int ii, ff, oo; cin >> ii >> ff >> oo; + v.pb({ii, ff, oo, i, -1}); + } + } + + sort(all(v), [](Show a, Show b) { + return a.i < b.i; + }); + + N = v.size(); + for (int i = 0; i < N; ++i) { + for (int j = i + 1; j < N; ++j) + if (v[j].i >= v[i].f) { + v[i].nxt = j; + break; + } + + if (v[i].nxt == -1) + v[i].nxt = N; } - } - - sort(all(v), [](Show a, Show b) { - return a.i < b.i; - }); - - N = v.size(); - for (int i = 0; i < N; ++i) { - for (int j = i + 1; j < N; ++j) - if (v[j].i >= v[i].f) { - v[i].nxt = j; - break; - } - - if (v[i].nxt == -1) - v[i].nxt = N; - } - - mset(dp, -1); - cout << max(-1, solve(0, 0)) << ende; - return 0; + + mset(dp, -1); + cout << max(-1, solve(0, 0)) << ende; + return 0; } diff --git a/contests/SBC18/G.cpp b/contests/SBC18/G.cpp index 6ff4450327af07a81e2e1974e2ab3acb947d628f..966d458bd0427c2a9df666a020c62a7fe5c6fc3f 100644 --- a/contests/SBC18/G.cpp +++ b/contests/SBC18/G.cpp @@ -23,115 +23,115 @@ using ii = pair<int,int>; using iii = pair<ii,int>; struct Dinic { - struct Edge { int u, f, c, r; }; + struct Edge { int u, f, c, r; }; - int N; - vector<int> depth, start; - vector<vector<Edge>> graph; + int N; + vector<int> depth, start; + vector<vector<Edge>> graph; - Dinic(int N) : - N(N), depth(N), start(N), graph(N) {} + Dinic(int N) : + N(N), depth(N), start(N), graph(N) {} - void add_edge(int u, int v, int c) { - Edge forw = { v, 0, c, (int) graph[v].size() }; - Edge back = { u, 0, 0, (int) graph[u].size() }; - graph[u].pb(forw); - graph[v].pb(back); - } + void add_edge(int u, int v, int c) { + Edge forw = { v, 0, c, (int) graph[v].size() }; + Edge back = { u, 0, 0, (int) graph[u].size() }; + graph[u].pb(forw); + graph[v].pb(back); + } - bool bfs(int s, int t) { - queue<int> Q; - Q.push(s); + bool bfs(int s, int t) { + queue<int> Q; + Q.push(s); - fill(all(depth), -1); - depth[s] = 0; + fill(all(depth), -1); + depth[s] = 0; - while (!Q.empty()) { - int v = Q.front(); Q.pop(); + while (!Q.empty()) { + int v = Q.front(); Q.pop(); - for (auto i : graph[v]) - if (depth[i.u] == -1 && i.f < i.c) { - depth[i.u] = depth[v] + 1; - Q.push(i.u); + for (auto i : graph[v]) + if (depth[i.u] == -1 && i.f < i.c) { + depth[i.u] = depth[v] + 1; + Q.push(i.u); + } } - } - return depth[t] != -1; - } + return depth[t] != -1; + } - int dfs(int s, int t, int f) { - if (s == t) return f; + int dfs(int s, int t, int f) { + if (s == t) return f; - for ( ; start[s] < graph[s].size(); ++start[s]) { - Edge &e = graph[s][start[s]]; + for ( ; start[s] < graph[s].size(); ++start[s]) { + Edge &e = graph[s][start[s]]; - if (depth[e.u] == depth[s] + 1 && e.f < e.c) { - int min_f = dfs(e.u, t, min(f, e.c - e.f)); + if (depth[e.u] == depth[s] + 1 && e.f < e.c) { + int min_f = dfs(e.u, t, min(f, e.c - e.f)); - if (min_f > 0) { - e.f += min_f; - graph[e.u][e.r].f -= min_f; - return min_f; + if (min_f > 0) { + e.f += min_f; + graph[e.u][e.r].f -= min_f; + return min_f; + } + } } - } + + return 0; } - return 0; - } - - int run(int s, int t) { - int ans = 0; - while (bfs(s, t)) { - fill(all(start), 0); - while (int flow = dfs(s, t, inf)) - ans += flow; + int run(int s, int t) { + int ans = 0; + while (bfs(s, t)) { + fill(all(start), 0); + while (int flow = dfs(s, t, inf)) + ans += flow; + } + return ans; } - return ans; - } }; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int p, r, c; cin >> p >> r >> c; - vector<int> vp(p); - vector<int> vr(r); - - int sum = 0; - for (auto &i : vp) { - cin >> i; - sum += i; - } - - for (auto &i : vr) cin >> i; - - vector<iii> v(c); - for (int i = 0; i < c; ++i) { - int a, b, x; cin >> a >> b >> x; - v[i] = {{a, b}, x}; - } - - int L = 0, R = 1001000; - for (int i = 0; i < 30; ++i) { - int m = (L + R) / 2; - - Dinic dinic(r + p + 5); - for (int j = 0; j < r; ++j) - dinic.add_edge(0, j + 1, vr[j]); - for (int j = 0; j < p; ++j) - dinic.add_edge(j + 1 + r, r + p + 4, vp[j]); - - for (int j = 0; j < c; ++j) - if (v[j].se <= m) - dinic.add_edge(v[j].fi.se, v[j].fi.fi + r, inf); - - if (dinic.run(0, r + p + 4) < sum) - L = m; - else - R= m; - } - - cout << ((R > 1000100) ? -1 : R) << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int p, r, c; cin >> p >> r >> c; + vector<int> vp(p); + vector<int> vr(r); + + int sum = 0; + for (auto &i : vp) { + cin >> i; + sum += i; + } + + for (auto &i : vr) cin >> i; + + vector<iii> v(c); + for (int i = 0; i < c; ++i) { + int a, b, x; cin >> a >> b >> x; + v[i] = {{a, b}, x}; + } + + int L = 0, R = 1001000; + for (int i = 0; i < 30; ++i) { + int m = (L + R) / 2; + + Dinic dinic(r + p + 5); + for (int j = 0; j < r; ++j) + dinic.add_edge(0, j + 1, vr[j]); + for (int j = 0; j < p; ++j) + dinic.add_edge(j + 1 + r, r + p + 4, vp[j]); + + for (int j = 0; j < c; ++j) + if (v[j].se <= m) + dinic.add_edge(v[j].fi.se, v[j].fi.fi + r, inf); + + if (dinic.run(0, r + p + 4) < sum) + L = m; + else + R= m; + } + + cout << ((R > 1000100) ? -1 : R) << ende; + return 0; } diff --git a/contests/SBC18/I.cpp b/contests/SBC18/I.cpp index aa2d90aa120e4c4f170d4294ed9cfa67cea7b8c2..57c8d66df4251422a4a7196d7caf05b4955ffe78 100644 --- a/contests/SBC18/I.cpp +++ b/contests/SBC18/I.cpp @@ -22,45 +22,45 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int n, m; cin >> n >> m; - int l; cin >> l; - int acc = 0; + int n, m; cin >> n >> m; + int l; cin >> l; + int acc = 0; - vector<int> lamp(m); - for (int i = 0; i < l; ++i) { - int x; cin >> x; x--; - lamp[x] = 1; - acc++; - } + vector<int> lamp(m); + for (int i = 0; i < l; ++i) { + int x; cin >> x; x--; + lamp[x] = 1; + acc++; + } - vector<vector<int>> inte(n); - for (int i = 0; i < n; ++i) { - int k; cin >> k; - for (int j = 0; j < k; ++j) { - int x; cin >> x; x--; - inte[i].pb(x); + vector<vector<int>> inte(n); + for (int i = 0; i < n; ++i) { + int k; cin >> k; + for (int j = 0; j < k; ++j) { + int x; cin >> x; x--; + inte[i].pb(x); + } } - } - if (acc == 0) - return cout << 0 << ende, 0; + if (acc == 0) + return cout << 0 << ende, 0; - int ans = 0; - for (int i = 0; i < 2; ++i) { - for (int j = 0; j < n; ++j) { - ans++; - for (auto k : inte[j]) - if (lamp[k]) { acc--; lamp[k] = 0; } - else { acc++; lamp[k] = 1; } + int ans = 0; + for (int i = 0; i < 2; ++i) { + for (int j = 0; j < n; ++j) { + ans++; + for (auto k : inte[j]) + if (lamp[k]) { acc--; lamp[k] = 0; } + else { acc++; lamp[k] = 1; } - if (acc == 0) - return cout << ans << ende, 0; + if (acc == 0) + return cout << ans << ende, 0; + } } - } - cout << -1 << ende; - return 0; + cout << -1 << ende; + return 0; } diff --git a/contests/SBC18/J.cpp b/contests/SBC18/J.cpp index 951df4e47bc686f90b9cb2837fa354d414e5d5ca..8a100cfb448476bf3d5a35815dde10b2d90fde55 100644 --- a/contests/SBC18/J.cpp +++ b/contests/SBC18/J.cpp @@ -28,36 +28,36 @@ double dist[MAX][MAX]; double dp[MAX][1 << MAXT]; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - cout << setprecision(5) << fixed; + ios::sync_with_stdio(0); + cin.tie(0); + cout << setprecision(5) << fixed; - int n, k; cin >> n >> k; - vector<dd> v(n); - for (int i = 0; i < n; ++i) - cin >> v[i].fi >> v[i].se; + int n, k; cin >> n >> k; + vector<dd> v(n); + for (int i = 0; i < n; ++i) + cin >> v[i].fi >> v[i].se; + + for (int i = 0; i < n; ++i) + for (int j = 0; j < n; ++j) + dist[i][j] = hypot(v[i].fi - v[j].fi, v[i].se - v[j].se); - for (int i = 0; i < n; ++i) - for (int j = 0; j < n; ++j) - dist[i][j] = hypot(v[i].fi - v[j].fi, v[i].se - v[j].se); + fill(dp[0], dp[0] + (MAX * (1 << MAXT)), 1e9); + for (int i = 0; i < k; ++i) + dp[i][1 << i] = 0; - fill(dp[0], dp[0] + (MAX * (1 << MAXT)), 1e9); - for (int i = 0; i < k; ++i) - dp[i][1 << i] = 0; + for (int mask = 1; mask < (1 << k); ++mask) { + for (int i = 0; i < n; ++i) + for (int ss = mask; ss > 0; ss = (ss - 1) & mask) + dp[i][mask] = min(dp[i][mask], dp[i][ss] + dp[i][mask ^ ss]); - for (int mask = 1; mask < (1 << k); ++mask) { - for (int i = 0; i < n; ++i) - for (int ss = mask; ss > 0; ss = (ss - 1) & mask) - dp[i][mask] = min(dp[i][mask], dp[i][ss] + dp[i][mask ^ ss]); + for (int i = 0; i < n; ++i) + for (int j = k; j < n; ++j) + dp[j][mask] = min(dp[j][mask], dp[i][mask] + dist[i][j]); + } + double ans = 1e9; for (int i = 0; i < n; ++i) - for (int j = k; j < n; ++j) - dp[j][mask] = min(dp[j][mask], dp[i][mask] + dist[i][j]); - } - - double ans = 1e9; - for (int i = 0; i < n; ++i) - ans = min(ans, dp[i][(1 << k) - 1]); - cout << ans << ende; - return 0; + ans = min(ans, dp[i][(1 << k) - 1]); + cout << ans << ende; + return 0; } diff --git a/contests/SBC18/L.cpp b/contests/SBC18/L.cpp index 8444e6f36c00f029b13d2a2b1472c2b336d5a64b..d50306a8d368a2804d87fdd7bdf62801868f0b9b 100644 --- a/contests/SBC18/L.cpp +++ b/contests/SBC18/L.cpp @@ -28,77 +28,77 @@ int par[MAX][MLOG]; vector<int> graph[MAX]; void dfs(int x, int p) { - par[x][0] = p; + par[x][0] = p; - if (p != -1) - h[x] = h[p] + 1; + if (p != -1) + h[x] = h[p] + 1; - for (int i = 1; i < MLOG; ++i) - if (par[x][i-1] != -1) - par[x][i] = par[par[x][i-1]][i-1]; + for (int i = 1; i < MLOG; ++i) + if (par[x][i-1] != -1) + par[x][i] = par[par[x][i-1]][i-1]; - for (auto i : graph[x]) - if (i != p) - dfs(i, x); + for (auto i : graph[x]) + if (i != p) + dfs(i, x); } int lca(int a, int b) { - if (h[a] < h[b]) - swap(a, b); + if (h[a] < h[b]) + swap(a, b); - for (int i = MLOG - 1; i >= 0; --i) - if (par[a][i] != -1 && h[par[a][i]] >= h[b]) - a = par[a][i]; + for (int i = MLOG - 1; i >= 0; --i) + if (par[a][i] != -1 && h[par[a][i]] >= h[b]) + a = par[a][i]; - if (a == b) - return a; + if (a == b) + return a; - for (int i = MLOG - 1; i >= 0; --i) - if (par[a][i] != -1 && par[a][i] != par[b][i]) { - a = par[a][i]; - b = par[b][i]; - } + for (int i = MLOG - 1; i >= 0; --i) + if (par[a][i] != -1 && par[a][i] != par[b][i]) { + a = par[a][i]; + b = par[b][i]; + } - return par[a][0]; + return par[a][0]; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, q; cin >> n >> q; - for (int i = 0; i < n - 1; ++i) { - int a, b; cin >> a >> b; a--, b--; - graph[a].pb(b); - graph[b].pb(a); - } - - mset(h, 0); - mset(par, -1); - dfs(0, -1); - - for (int i = 0; i < q; ++i) { - int a, b, c, d; - cin >> a >> b >> c >> d; a--, b--, c--, d--; - vector<int> v = { lca(a, c), lca(a, d), lca(b, c), lca(b, d) }; - - sort(all(v), [&](int a, int b) { - return h[a] > h[b]; - }); - - if (v[0] == v[1]) { - bool t1 = ((lca(a, v[0]) == v[0] || lca(b, v[0]) == v[0]) && h[lca(a, b)] <= h[v[0]]); - bool t2 = ((lca(c, v[0]) == v[0] || lca(d, v[0]) == v[0]) && h[lca(c, d)] <= h[v[0]]); - cout << (t1 && t2) << ende; - } else { - int aux = lca(v[0], v[1]); - - if (aux == v[0] || aux == v[1]) - cout << abs(h[v[0]] - h[v[1]]) + 1 << ende; - else - cout << (h[v[0]] - h[aux] + 1) + (h[v[1]] - h[aux] + 1) - 1 << ende; + ios::sync_with_stdio(0); + cin.tie(0); + + int n, q; cin >> n >> q; + for (int i = 0; i < n - 1; ++i) { + int a, b; cin >> a >> b; a--, b--; + graph[a].pb(b); + graph[b].pb(a); + } + + mset(h, 0); + mset(par, -1); + dfs(0, -1); + + for (int i = 0; i < q; ++i) { + int a, b, c, d; + cin >> a >> b >> c >> d; a--, b--, c--, d--; + vector<int> v = { lca(a, c), lca(a, d), lca(b, c), lca(b, d) }; + + sort(all(v), [&](int a, int b) { + return h[a] > h[b]; + }); + + if (v[0] == v[1]) { + bool t1 = ((lca(a, v[0]) == v[0] || lca(b, v[0]) == v[0]) && h[lca(a, b)] <= h[v[0]]); + bool t2 = ((lca(c, v[0]) == v[0] || lca(d, v[0]) == v[0]) && h[lca(c, d)] <= h[v[0]]); + cout << (t1 && t2) << ende; + } else { + int aux = lca(v[0], v[1]); + + if (aux == v[0] || aux == v[1]) + cout << abs(h[v[0]] - h[v[1]]) + 1 << ende; + else + cout << (h[v[0]] - h[aux] + 1) + (h[v[1]] - h[aux] + 1) - 1 << ende; + } } - } - return 0; + return 0; } diff --git a/contests/SBC19/A.cpp b/contests/SBC19/A.cpp index e8be3f8609d795ddad748329878aa8ae48639cc8..e5bad7660c516e9e6cc2e51bad7ce3f37623c6aa 100644 --- a/contests/SBC19/A.cpp +++ b/contests/SBC19/A.cpp @@ -21,12 +21,12 @@ using ll = long long; using ii = pair<int,int>; struct Circle { - int x, y, r; - Circle() {} + int x, y, r; + Circle() {} - bool inter(Circle c) { - return (c.x - x)*(c.x - x) + (c.y - y)*(c.y - y) <= (c.r + r)*(c.r + r); - } + bool inter(Circle c) { + return (c.x - x)*(c.x - x) + (c.y - y)*(c.y - y) <= (c.r + r)*(c.r + r); + } }; #define R 1001 @@ -38,50 +38,50 @@ int par[MAX]; int rnk[MAX]; int find_set(int x) { - if (par[x] != x) - par[x] = find_set(par[x]); - return par[x]; + if (par[x] != x) + par[x] = find_set(par[x]); + return par[x]; } void union_set(int a, int b) { - a = find_set(a); - b = find_set(b); + a = find_set(a); + b = find_set(b); - if (a == b) return; - if (rnk[a] < rnk[b]) swap(a, b); - if (rnk[a] == rnk[b]) rnk[a]++; - par[b] = a; + if (a == b) return; + if (rnk[a] < rnk[b]) swap(a, b); + if (rnk[a] == rnk[b]) rnk[a]++; + par[b] = a; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int m, n, k; cin >> m >> n >> k; - vector<Circle> v(k); - - for (auto &i : v) - cin >> i.x >> i.y >> i.r; - - iota(par, par + MAX, 0); - for (int i = 0; i < k; ++i) { - for (int j = 0; j < k; ++j) - if (v[i].inter(v[j])) - union_set(i, j); - - if (v[i].x + v[i].r >= m) union_set(R, i); - if (v[i].x - v[i].r <= 0) union_set(L, i); - if (v[i].y + v[i].r >= n) union_set(U, i); - if (v[i].y - v[i].r <= 0) union_set(D, i); - } - - if (find_set(R) == find_set(L) || - find_set(L) == find_set(D) || - find_set(U) == find_set(D) || - find_set(R) == find_set(U)) - cout << "N" << ende; - else - cout << "S" << ende; - - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int m, n, k; cin >> m >> n >> k; + vector<Circle> v(k); + + for (auto &i : v) + cin >> i.x >> i.y >> i.r; + + iota(par, par + MAX, 0); + for (int i = 0; i < k; ++i) { + for (int j = 0; j < k; ++j) + if (v[i].inter(v[j])) + union_set(i, j); + + if (v[i].x + v[i].r >= m) union_set(R, i); + if (v[i].x - v[i].r <= 0) union_set(L, i); + if (v[i].y + v[i].r >= n) union_set(U, i); + if (v[i].y - v[i].r <= 0) union_set(D, i); + } + + if (find_set(R) == find_set(L) || + find_set(L) == find_set(D) || + find_set(U) == find_set(D) || + find_set(R) == find_set(U)) + cout << "N" << ende; + else + cout << "S" << ende; + + return 0; } diff --git a/contests/SBC19/B.cpp b/contests/SBC19/B.cpp index db754cb414921a22e0370a292ce117a9f8f15344..5c86b4ae9fc48b5625158be9efe475b4711a5a88 100644 --- a/contests/SBC19/B.cpp +++ b/contests/SBC19/B.cpp @@ -20,13 +20,13 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int n; cin >> n; - vector<int> v(n); - for (auto &i : v) cin >> i; + int n; cin >> n; + vector<int> v(n); + for (auto &i : v) cin >> i; - cout << ((*max_element(all(v)) == v[0]) ? "S" : "N") << ende; - return 0; + cout << ((*max_element(all(v)) == v[0]) ? "S" : "N") << ende; + return 0; } diff --git a/contests/SBC19/D.cpp b/contests/SBC19/D.cpp index 08b1b28966490feaa598f88f6edd947be8fddf18..eedf1efb734bbcc4d1b51ad1c5c1fe424305bf0e 100644 --- a/contests/SBC19/D.cpp +++ b/contests/SBC19/D.cpp @@ -26,45 +26,45 @@ int sz[MAX]; vector<int> graph[MAX]; int dfs(int x, int p = -1) { - par[x] = p; + par[x] = p; - int max_size = 0; - for (auto i : graph[x]) - if (i != p) { - int isize = dfs(i, x); - if (isize > max_size) - max_size = isize, heavy[x] = i; - } + int max_size = 0; + for (auto i : graph[x]) + if (i != p) { + int isize = dfs(i, x); + if (isize > max_size) + max_size = isize, heavy[x] = i; + } - return max_size + 1; + return max_size + 1; } void decompose(int x, int h = 0) { - sz[h]++; + sz[h]++; - if (heavy[x] != -1) - decompose(heavy[x], h); - for (auto i : graph[x]) - if (i != par[x] && i != heavy[x]) - decompose(i, i); + if (heavy[x] != -1) + decompose(heavy[x], h); + for (auto i : graph[x]) + if (i != par[x] && i != heavy[x]) + decompose(i, i); } int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int n, k; cin >> n >> k; - for (int i = 2; i <= n; ++i) { - int x; cin >> x; - graph[x-1].pb(i-1); - graph[i-1].pb(x-1); - } + int n, k; cin >> n >> k; + for (int i = 2; i <= n; ++i) { + int x; cin >> x; + graph[x-1].pb(i-1); + graph[i-1].pb(x-1); + } - mset(heavy, -1); - dfs(0); - decompose(0); + mset(heavy, -1); + dfs(0); + decompose(0); - sort(sz, sz + MAX); - cout << accumulate(sz + MAX - k, sz + MAX, 0) << ende; - return 0; + sort(sz, sz + MAX); + cout << accumulate(sz + MAX - k, sz + MAX, 0) << ende; + return 0; } diff --git a/contests/SBC19/F.cpp b/contests/SBC19/F.cpp index 6e6fc57044bbad5fa8d14f2e038774fa1eaf22b0..849214009a43bb046b81d4dda042a0468fa0cd7a 100644 --- a/contests/SBC19/F.cpp +++ b/contests/SBC19/F.cpp @@ -27,40 +27,40 @@ int N = 100001; int tree[MAX*4], cnt[MAX*4]; void update(int i, int j, int val, - int node = 1, int l = 0, int r = N - 1) { - if (l > r || l > j || r < i) return; - - if (i <= l && r <= j) - tree[node] += val; - else { - int m = (l + r) / 2; - update(i, j, val, left(node), l, m); - update(i, j, val, right(node), m + 1, r); - } - - if (tree[node]) - cnt[node] = r - l + 1; - else { - cnt[node] = 0; - if (l < r) cnt[node] = cnt[left(node)] + cnt[right(node)]; - } + int node = 1, int l = 0, int r = N - 1) { + if (l > r || l > j || r < i) return; + + if (i <= l && r <= j) + tree[node] += val; + else { + int m = (l + r) / 2; + update(i, j, val, left(node), l, m); + update(i, j, val, right(node), m + 1, r); + } + + if (tree[node]) + cnt[node] = r - l + 1; + else { + cnt[node] = 0; + if (l < r) cnt[node] = cnt[left(node)] + cnt[right(node)]; + } } struct Segment { - int x1, y1, x2, y2; + int x1, y1, x2, y2; - Segment() {} - Segment(int x1, int y1, int x2, int y2) : - x1(x1), y1(y1), x2(x2), y2(y2) {} + Segment() {} + Segment(int x1, int y1, int x2, int y2) : + x1(x1), y1(y1), x2(x2), y2(y2) {} }; struct Event { - int x1, x2, y; - int beg; + int x1, x2, y; + int beg; - Event() {} - Event(int x1, int x2, int y, int b) : - x1(x1), x2(x2), y(y), beg(b) {} + Event() {} + Event(int x1, int x2, int y, int b) : + x1(x1), x2(x2), y(y), beg(b) {} }; Segment rect; @@ -68,55 +68,55 @@ vector<Event> E; vector<Segment> ss; double calc(int m, ll p) { - mset(tree, 0); - mset(cnt, 0); - - int k = 0; - for (int i = 0; i < ss.size(); ++i) { - E[k++] = Event(ss[i].x1 - m, ss[i].x2 + m, ss[i].y1 - m, 1); - E[k++] = Event(ss[i].x1 - m, ss[i].x2 + m, ss[i].y2 + m, -1); - } - - sort(all(E), [&](const Event &a, const Event &b) { - return a.y < b.y; - }); - - k = 0; - ll ans = 0; - for (int i = rect.y1; i < rect.y2; ++i) { - for (; k < E.size() && E[k].y <= i; ++k) - if (E[k].x1 <= rect.x2 - 1 && E[k].x2 >= rect.x1) - update(max(rect.x1, E[k].x1), min(rect.x2 - 1, E[k].x2 - 1), E[k].beg); - ans += (ll) cnt[1]; - } - - return (ans*100) < p * ((ll) ((ll) rect.x2 - rect.x1) * ((ll) rect.y2 - rect.y1)); + mset(tree, 0); + mset(cnt, 0); + + int k = 0; + for (int i = 0; i < ss.size(); ++i) { + E[k++] = Event(ss[i].x1 - m, ss[i].x2 + m, ss[i].y1 - m, 1); + E[k++] = Event(ss[i].x1 - m, ss[i].x2 + m, ss[i].y2 + m, -1); + } + + sort(all(E), [&](const Event &a, const Event &b) { + return a.y < b.y; + }); + + k = 0; + ll ans = 0; + for (int i = rect.y1; i < rect.y2; ++i) { + for (; k < E.size() && E[k].y <= i; ++k) + if (E[k].x1 <= rect.x2 - 1 && E[k].x2 >= rect.x1) + update(max(rect.x1, E[k].x1), min(rect.x2 - 1, E[k].x2 - 1), E[k].beg); + ans += (ll) cnt[1]; + } + + return (ans*100) < p * ((ll) ((ll) rect.x2 - rect.x1) * ((ll) rect.y2 - rect.y1)); } int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); + + int n; cin >> n; + E.resize(2*n); + ss.resize(n); - int n; cin >> n; - E.resize(2*n); - ss.resize(n); + for (auto &i : ss) { + int x1, y1, x2, y2; + cin >> x1 >> y1 >> x2 >> y2; + i = Segment(min(x1,x2), min(y1,y2), max(x1,x2), max(y1,y2)); + } - for (auto &i : ss) { + ll p; cin >> p; int x1, y1, x2, y2; cin >> x1 >> y1 >> x2 >> y2; - i = Segment(min(x1,x2), min(y1,y2), max(x1,x2), max(y1,y2)); - } - - ll p; cin >> p; - int x1, y1, x2, y2; - cin >> x1 >> y1 >> x2 >> y2; - rect = Segment(min(x1,x2), min(y1,y2), max(x1,x2), max(y1,y2)); + rect = Segment(min(x1,x2), min(y1,y2), max(x1,x2), max(y1,y2)); - int l = 0, r = 101010; - for (int b = r / 2; b >= 1; b /= 2) - while (calc(l + b, p)) - l += b; + int l = 0, r = 101010; + for (int b = r / 2; b >= 1; b /= 2) + while (calc(l + b, p)) + l += b; - cout << l + 1 << ende; - return 0; + cout << l + 1 << ende; + return 0; } diff --git a/contests/SBC19/G.cpp b/contests/SBC19/G.cpp index 2c8ce39e7a557f400e9f28dac5cfc698c73c6f65..3c614e3deb7ad1862a254c42f1cb3dad01bbc948 100644 --- a/contests/SBC19/G.cpp +++ b/contests/SBC19/G.cpp @@ -20,104 +20,104 @@ using ll = long long; using ii = pair<int,int>; struct MinCostMaxFlow { - struct Edge { - int u, v, cap; - double cost; - }; - - vector<Edge> edges; - vector<vector<int>> adj; - vector<int> vis, par, ind; - vector<double> dist; - - MinCostMaxFlow(int N) : - vis(N), dist(N), par(N), ind(N), adj(N) {} - - void add_edge(int u, int v, int cap, double cost) { - adj[u].pb(edges.size()); - edges.pb({ u, v, cap, cost }); - - adj[v].pb(edges.size()); - edges.pb({ v, u, 0, -cost }); - } - - bool spfa(int s, int t) { - fill(all(dist), inf); - dist[s] = 0; - - queue<int> Q; - Q.push(s); - - while (!Q.empty()) { - int u = Q.front(); Q.pop(); - vis[u] = 0; - - for (auto i : adj[u]) { - Edge &e = edges[i]; - int v = e.v; - - if (e.cap > 0 && dist[v] > dist[u] + e.cost) { - dist[v] = dist[u] + e.cost; - par[v] = u; - ind[v] = i; - - if (!vis[v]) { - Q.push(v); - vis[v] = 1; - } + struct Edge { + int u, v, cap; + double cost; + }; + + vector<Edge> edges; + vector<vector<int>> adj; + vector<int> vis, par, ind; + vector<double> dist; + + MinCostMaxFlow(int N) : + vis(N), dist(N), par(N), ind(N), adj(N) {} + + void add_edge(int u, int v, int cap, double cost) { + adj[u].pb(edges.size()); + edges.pb({ u, v, cap, cost }); + + adj[v].pb(edges.size()); + edges.pb({ v, u, 0, -cost }); + } + + bool spfa(int s, int t) { + fill(all(dist), inf); + dist[s] = 0; + + queue<int> Q; + Q.push(s); + + while (!Q.empty()) { + int u = Q.front(); Q.pop(); + vis[u] = 0; + + for (auto i : adj[u]) { + Edge &e = edges[i]; + int v = e.v; + + if (e.cap > 0 && dist[v] > dist[u] + e.cost) { + dist[v] = dist[u] + e.cost; + par[v] = u; + ind[v] = i; + + if (!vis[v]) { + Q.push(v); + vis[v] = 1; + } + } + } } - } + + return dist[t] < inf; } - return dist[t] < inf; - } - - void run(int s, int t) { - double min_cost = 0; - int max_flow = 0; - - while (spfa(s, t)) { - int flow = inf; - for (int i = t; i != s; i = par[i]) - flow = min(flow, edges[ind[i]].cap); - - for (int i = t; i != s; i = par[i]) { - edges[ind[i] ].cap -= flow; - edges[ind[i]^1].cap += flow; - } - - min_cost += flow * dist[t]; - max_flow += flow; + void run(int s, int t) { + double min_cost = 0; + int max_flow = 0; + + while (spfa(s, t)) { + int flow = inf; + for (int i = t; i != s; i = par[i]) + flow = min(flow, edges[ind[i]].cap); + + for (int i = t; i != s; i = par[i]) { + edges[ind[i] ].cap -= flow; + edges[ind[i]^1].cap += flow; + } + + min_cost += flow * dist[t]; + max_flow += flow; + } } - } }; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int n; cin >> n; + int n; cin >> n; - MinCostMaxFlow mcmf(2*n + 2); - for (int i = 0; i < n; ++i) { - mcmf.add_edge(0, i+1, 1, 0); - for (int j = 0; j < n; ++j) { - double x; cin >> x; - mcmf.add_edge(i+1, j+1+n, 1, -log(x)); + MinCostMaxFlow mcmf(2*n + 2); + for (int i = 0; i < n; ++i) { + mcmf.add_edge(0, i+1, 1, 0); + for (int j = 0; j < n; ++j) { + double x; cin >> x; + mcmf.add_edge(i+1, j+1+n, 1, -log(x)); + } + mcmf.add_edge(i+n+1, 2*n+1, 1, 0); } - mcmf.add_edge(i+n+1, 2*n+1, 1, 0); - } - - vector<int> ans(n); - mcmf.run(0, 2*n+1); - for (int i = 0; i < mcmf.edges.size(); ++i) - if (mcmf.edges[i].u > 0 && mcmf.edges[i].u <= n && - mcmf.edges[i].v >= n+1 && mcmf.edges[i].v < 2*n+1 && - mcmf.edges[i].cap == 0) - ans[mcmf.edges[i].v-(n+1)] = mcmf.edges[i].u; - - for (auto i : ans) - cout << i << " "; - cout << ende; - return 0; + + vector<int> ans(n); + mcmf.run(0, 2*n+1); + for (int i = 0; i < mcmf.edges.size(); ++i) + if (mcmf.edges[i].u > 0 && mcmf.edges[i].u <= n && + mcmf.edges[i].v >= n+1 && mcmf.edges[i].v < 2*n+1 && + mcmf.edges[i].cap == 0) + ans[mcmf.edges[i].v-(n+1)] = mcmf.edges[i].u; + + for (auto i : ans) + cout << i << " "; + cout << ende; + return 0; } diff --git a/contests/SBC19/H.cpp b/contests/SBC19/H.cpp index 8cad16d1d590fa7e9972bbdd378065b1f721b509..5a1b11a7cbc1952f86c32cda755d1a25b648b91d 100644 --- a/contests/SBC19/H.cpp +++ b/contests/SBC19/H.cpp @@ -20,14 +20,14 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int v, n; cin >> v >> n; - for (int i = 1; i < 10; ++i) { - if (i > 1) cout << " "; - cout << ((v*n*i) - 1) / 10 + 1; - } - cout << ende; - return 0; + int v, n; cin >> v >> n; + for (int i = 1; i < 10; ++i) { + if (i > 1) cout << " "; + cout << ((v*n*i) - 1) / 10 + 1; + } + cout << ende; + return 0; } diff --git a/contests/SBC19/I.cpp b/contests/SBC19/I.cpp index 0f929cb156139ea3b366a708ecc0df7276242a0b..a752efcda3d151ee4eeb0539ffe33b293b689b7d 100644 --- a/contests/SBC19/I.cpp +++ b/contests/SBC19/I.cpp @@ -25,61 +25,61 @@ int dist[2][MAX][MAX]; struct Query { int idx, a, b, k, t; }; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, r; cin >> n >> r; - vector<ii> T[2]; - for (int i = 0; i < n; ++i) { - int x; cin >> x; - T[0].pb({x, i}); - T[1].pb({x, i}); - dist[0][i][i] = dist[1][i][i] = 0; - } - - sort(all(T[0])); - sort(rall(T[1])); - - mset(dist, inf); - for (int i = 0; i < r; ++i) { - int a, b, c; cin >> a >> b >> c; a--, b--; - dist[0][a][b] = dist[1][a][b] = c; - dist[0][b][a] = dist[1][b][a] = c; - } - - int q; cin >> q; - vector<Query> Q(q); - for (int i = 0; i < q; ++i) { - int a, b, k, t; cin >> a >> b >> k >> t; a--, b--; - Q[i] = Query{i, a, b, k, t}; - } - - sort(all(Q), [&](Query a, Query b) { - if (a.t == b.t) return a.k < b.k; - return a.t < b.t; - }); - - int curr = 0; - vector<int> ans(q); - for (int tt = 0; tt <= 1; ++tt) { - int kk = 1; - for (int k = 0; k < n; ++k) { - if (k && T[tt][k].fi != T[tt][k-1].fi) { - for (; curr < q && Q[curr].k == kk && Q[curr].t == tt; ++curr) - ans[Q[curr].idx] = dist[tt][Q[curr].a][Q[curr].b]; - kk++; - } - - for (int i = 0; i < n; ++i) - for (int j = 0; j < n; ++j) - dist[tt][i][j] = min(dist[tt][i][j], dist[tt][i][T[tt][k].se] + dist[tt][T[tt][k].se][j]); + ios::sync_with_stdio(0); + cin.tie(0); + + int n, r; cin >> n >> r; + vector<ii> T[2]; + for (int i = 0; i < n; ++i) { + int x; cin >> x; + T[0].pb({x, i}); + T[1].pb({x, i}); + dist[0][i][i] = dist[1][i][i] = 0; } - for (; curr < q && Q[curr].t == tt; ++curr) - ans[Q[curr].idx] = dist[tt][Q[curr].a][Q[curr].b]; - } + sort(all(T[0])); + sort(rall(T[1])); - for (auto i : ans) - cout << ((i == inf) ? -1 : i) << ende; - return 0; + mset(dist, inf); + for (int i = 0; i < r; ++i) { + int a, b, c; cin >> a >> b >> c; a--, b--; + dist[0][a][b] = dist[1][a][b] = c; + dist[0][b][a] = dist[1][b][a] = c; + } + + int q; cin >> q; + vector<Query> Q(q); + for (int i = 0; i < q; ++i) { + int a, b, k, t; cin >> a >> b >> k >> t; a--, b--; + Q[i] = Query{i, a, b, k, t}; + } + + sort(all(Q), [&](Query a, Query b) { + if (a.t == b.t) return a.k < b.k; + return a.t < b.t; + }); + + int curr = 0; + vector<int> ans(q); + for (int tt = 0; tt <= 1; ++tt) { + int kk = 1; + for (int k = 0; k < n; ++k) { + if (k && T[tt][k].fi != T[tt][k-1].fi) { + for (; curr < q && Q[curr].k == kk && Q[curr].t == tt; ++curr) + ans[Q[curr].idx] = dist[tt][Q[curr].a][Q[curr].b]; + kk++; + } + + for (int i = 0; i < n; ++i) + for (int j = 0; j < n; ++j) + dist[tt][i][j] = min(dist[tt][i][j], dist[tt][i][T[tt][k].se] + dist[tt][T[tt][k].se][j]); + } + + for (; curr < q && Q[curr].t == tt; ++curr) + ans[Q[curr].idx] = dist[tt][Q[curr].a][Q[curr].b]; + } + + for (auto i : ans) + cout << ((i == inf) ? -1 : i) << ende; + return 0; } diff --git a/contests/SBC19/J.cpp b/contests/SBC19/J.cpp index ec4c5b8e4656088abecb99054edc34fbbfe47637..0f7fda12d5a921276032e0fd8e8e94d8116f9140 100644 --- a/contests/SBC19/J.cpp +++ b/contests/SBC19/J.cpp @@ -22,50 +22,50 @@ using ii = pair<int,int>; int cnt[20][300]; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - int n, k; cin >> n >> k; k--; - vector<string> v(n); - for (int i = 0; i < n; ++i) { - cin >> v[i]; - for (auto j : v[i]) - cnt[i][j]++; + int n, k; cin >> n >> k; k--; + vector<string> v(n); + for (int i = 0; i < n; ++i) { + cin >> v[i]; + for (auto j : v[i]) + cnt[i][j]++; - if (cnt[i][v[i][0]] == 4 && i != k) - return cout << i + 1 << ende, 0; - } + if (cnt[i][v[i][0]] == 4 && i != k) + return cout << i + 1 << ende, 0; + } - string ord = "A23456789DQJK"; + string ord = "A23456789DQJK"; - cnt[k]['C']++; - int curr = k; - bool pode = false; - while (1) { - bool pass = false; - if (cnt[curr]['C'] && pode) { - cnt[curr]['C']--; - cnt[(curr+1)%n]['C']++; - pass = true; - pode = false; - } else if (!cnt[curr]['C'] || !pode) { - int mx = -1; - for (int i = 0; i < ord.size(); ++i) - if (cnt[curr][ord[i]] != 0 && (mx == -1 || cnt[curr][ord[i]] < cnt[curr][ord[mx]])) - mx = i; + cnt[k]['C']++; + int curr = k; + bool pode = false; + while (1) { + bool pass = false; + if (cnt[curr]['C'] && pode) { + cnt[curr]['C']--; + cnt[(curr+1)%n]['C']++; + pass = true; + pode = false; + } else if (!cnt[curr]['C'] || !pode) { + int mx = -1; + for (int i = 0; i < ord.size(); ++i) + if (cnt[curr][ord[i]] != 0 && (mx == -1 || cnt[curr][ord[i]] < cnt[curr][ord[mx]])) + mx = i; - cnt[curr][ord[mx]]--; - cnt[(curr+1)%n][ord[mx]]++; - } + cnt[curr][ord[mx]]--; + cnt[(curr+1)%n][ord[mx]]++; + } - if (!cnt[curr]['C']) - for (int i = 0; i < ord.size(); ++i) - if (cnt[curr][ord[i]] == 4) - return cout << curr + 1 << ende, 0; + if (!cnt[curr]['C']) + for (int i = 0; i < ord.size(); ++i) + if (cnt[curr][ord[i]] == 4) + return cout << curr + 1 << ende, 0; - if (!pass) pode = true; - curr = (curr+1)%n; - } + if (!pass) pode = true; + curr = (curr+1)%n; + } - return 0; + return 0; } diff --git a/contests/SBC19/L.cpp b/contests/SBC19/L.cpp index 04ad5327ebe1b23bdecc67573f00de7a6c6f2037..808eb687cc471420a59e758acd19ad736ee602aa 100644 --- a/contests/SBC19/L.cpp +++ b/contests/SBC19/L.cpp @@ -20,11 +20,11 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - ll n; cin >> n; - cout << (1LL << __builtin_popcountll(n)) << ende; + ll n; cin >> n; + cout << (1LL << __builtin_popcountll(n)) << ende; - return 0; + return 0; } diff --git a/contests/SBC19/M.cpp b/contests/SBC19/M.cpp index 741935cbb1591c60285ca259c74410e9e2ebd825..b57b2f7d2b7f00c2cee03167e3801bde02e4da5f 100644 --- a/contests/SBC19/M.cpp +++ b/contests/SBC19/M.cpp @@ -20,31 +20,31 @@ using ll = long long; using ii = pair<int,int>; int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, c, t; cin >> n >> c >> t; - vector<int> v(n); - for (auto &i : v) cin >> i; - - auto f = [&](int x) { - int memb = 0; - for (int i = 0, j = 0; i < n; i = j, ++memb) { - for (int sum = 0; j < n && (sum+v[j]-1)/t+1 <= x; ++j) - sum += v[j]; - if (i == j) - return false; + ios::sync_with_stdio(0); + cin.tie(0); + + int n, c, t; cin >> n >> c >> t; + vector<int> v(n); + for (auto &i : v) cin >> i; + + auto f = [&](int x) { + int memb = 0; + for (int i = 0, j = 0; i < n; i = j, ++memb) { + for (int sum = 0; j < n && (sum+v[j]-1)/t+1 <= x; ++j) + sum += v[j]; + if (i == j) + return false; + } + return (memb <= c); + }; + + int l = 1, r = (accumulate(all(v), 0) - 1) / t + 1; + for (int i = 0; i < 50; ++i) { + int m = (l + r) / 2; + if (!f(m)) l = m+1; + else r = m-1; } - return (memb <= c); - }; - - int l = 1, r = (accumulate(all(v), 0) - 1) / t + 1; - for (int i = 0; i < 50; ++i) { - int m = (l + r) / 2; - if (!f(m)) l = m+1; - else r = m-1; - } - - cout << l << ende; - return 0; + + cout << l << ende; + return 0; } diff --git a/gen_notebook b/gen_notebook index a596a406e2ed5500eb6d91126908b755e5fafb97..0300deab3e19b24b3c195354284ca776553b5150 100755 --- a/gen_notebook +++ b/gen_notebook @@ -32,7 +32,7 @@ else rm latex_log.txt echo "PDF generated successfully: $output_name" else - rm $tex_file* + #rm $tex_file* echo "ERROR on LaTeX input file: check latex_log.txt" exit 1 fi diff --git a/misc/environment/template.cpp b/misc/environment/template.cpp index 1cc4ff5334b6ffbd3dbb2f0b79d02af9d5d659b8..862e42182e37442092ea17d3b905d0931f2853cc 100644 --- a/misc/environment/template.cpp +++ b/misc/environment/template.cpp @@ -2,6 +2,10 @@ #include <bits/stdc++.h> +#ifdef LOCAL +#include <local.h> +#endif + #define EPS 1e-6 #define MOD 1000000007 #define inf 0x3f3f3f3f @@ -18,12 +22,15 @@ using namespace std; -using ll = long long; -using ii = pair<int,int>; +using i64 = long long; +template <typename T> using p = pair<T,T>; + int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); + + - return 0; + return 0; } diff --git a/problems/a_simple_task.cpp b/problems/a_simple_task.cpp index d1d2ce9f126e418d853a81c393d403fc0e93891f..331ad5dd816c5c54a00f645f30d203bbc6469e5a 100644 --- a/problems/a_simple_task.cpp +++ b/problems/a_simple_task.cpp @@ -1,152 +1,152 @@ /// A Simple Task #include <bits/stdc++.h> - + #define MAX 100001 #define EPS 1e-6 #define MOD 1000000007 #define inf 0x3f3f3f3f #define llinf 0x3f3f3f3f3f3f3f3f - + #define fi first #define se second #define sz size() #define pb push_back #define ende '\n' - + #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() #define mset(x, y) memset(&x, (y), sizeof(x)) - + #define left(x) ((x << 1)) #define right(x) ((x << 1) + 1) - + using namespace std; - + typedef long long ll; typedef pair<int,int> ii; - + int N, q; int tree[4 * MAX][26], lazy[4 * MAX][26]; - + string s; - + void build(int node = 1, int a = 0, int b = N-1) { - if (a > b) - return; - - if (a == b) { - tree[node][s[a] - 'a'] = 1; - return; - } - - build(left(node), a, (a + b) / 2); - build(right(node), (a + b) / 2 + 1, b); - - for (int i = 0; i < 26; ++i) - tree[node][i] = tree[left(node)][i] + tree[right(node)][i]; + if (a > b) + return; + + if (a == b) { + tree[node][s[a] - 'a'] = 1; + return; + } + + build(left(node), a, (a + b) / 2); + build(right(node), (a + b) / 2 + 1, b); + + for (int i = 0; i < 26; ++i) + tree[node][i] = tree[left(node)][i] + tree[right(node)][i]; } - + void push(int let, int node, int a, int b, int val) { - tree[node][let] = (b - a + 1) * val; - - if (a != b) { - lazy[left(node)][let] = val; - lazy[right(node)][let] = val; - } - - lazy[node][let] = -1; + tree[node][let] = (b - a + 1) * val; + + if (a != b) { + lazy[left(node)][let] = val; + lazy[right(node)][let] = val; + } + + lazy[node][let] = -1; } - + void update(int let, int i, int j, int val, int node = 1, int a = 0, int b = N-1) { - if (lazy[node][let] != -1) - push(let, node, a, b, lazy[node][let]); - - if (a > b or a > j or b < i) - return; - - if (i <= a and b <= j) { - push(let, node, a, b, val); - return; - } - - update(let, i, j, val, left(node), a, (a + b) / 2); - update(let, i, j, val, right(node), (a + b) / 2 + 1, b); - tree[node][let] = tree[left(node)][let] + tree[right(node)][let]; + if (lazy[node][let] != -1) + push(let, node, a, b, lazy[node][let]); + + if (a > b or a > j or b < i) + return; + + if (i <= a and b <= j) { + push(let, node, a, b, val); + return; + } + + update(let, i, j, val, left(node), a, (a + b) / 2); + update(let, i, j, val, right(node), (a + b) / 2 + 1, b); + tree[node][let] = tree[left(node)][let] + tree[right(node)][let]; } - + int query(int let, int i, int j, int node = 1, int a = 0, int b = N-1) { - if (a > b || a > j || b < i) - return 0; - - if (lazy[node][let] != -1) - push(let, node, a, b, lazy[node][let]); - - if (a >= i and b <= j) - return tree[node][let]; - - int q1 = query(let, i, j, left(node), a, (a + b) / 2); - int q2 = query(let, i, j, right(node), (a + b) / 2 + 1, b); - return q1 + q2; + if (a > b || a > j || b < i) + return 0; + + if (lazy[node][let] != -1) + push(let, node, a, b, lazy[node][let]); + + if (a >= i and b <= j) + return tree[node][let]; + + int q1 = query(let, i, j, left(node), a, (a + b) / 2); + int q2 = query(let, i, j, right(node), (a + b) / 2 + 1, b); + return q1 + q2; } - + void get_ans(int let, string &ans, int node = 1, int l = 0, int r = N-1) { - if (lazy[node][let] != -1) - push(let, node, l, r, lazy[node][let]); - - if (!tree[node][let]) - return; - - if (l == r) { - ans[l] = let + 'a'; - return; - } - - get_ans(let, ans, left(node), l, (l+r)/2); - get_ans(let, ans, right(node), (l+r)/2 + 1, r); + if (lazy[node][let] != -1) + push(let, node, l, r, lazy[node][let]); + + if (!tree[node][let]) + return; + + if (l == r) { + ans[l] = let + 'a'; + return; + } + + get_ans(let, ans, left(node), l, (l+r)/2); + get_ans(let, ans, right(node), (l+r)/2 + 1, r); } - + int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - cin >> N >> q; - cin >> s; - - build(); - mset(lazy, -1); - - vector<int> cnt(26); - for (int i = 0; i < q; ++i) { - int a, b, k; cin >> a >> b >> k; - a--, b--; - for (int j = 0; j < 26; ++j) { - cnt[j] = query(j, a, b); - if (cnt[j]) update(j, a, b, 0); - } - - if (k) { - int bord = a; - for (int j = 0; j < 26; ++j) - if (cnt[j]) { - update(j, bord, bord + cnt[j] - 1, 1); - bord += cnt[j]; + ios::sync_with_stdio(0); + cin.tie(0); + + cin >> N >> q; + cin >> s; + + build(); + mset(lazy, -1); + + vector<int> cnt(26); + for (int i = 0; i < q; ++i) { + int a, b, k; cin >> a >> b >> k; + a--, b--; + for (int j = 0; j < 26; ++j) { + cnt[j] = query(j, a, b); + if (cnt[j]) update(j, a, b, 0); } - } else { - int bord = a; - for (int j = 25; j >= 0; --j) - if (cnt[j]) { - update(j, bord, bord + cnt[j] - 1, 1); - bord += cnt[j]; + + if (k) { + int bord = a; + for (int j = 0; j < 26; ++j) + if (cnt[j]) { + update(j, bord, bord + cnt[j] - 1, 1); + bord += cnt[j]; + } + } else { + int bord = a; + for (int j = 25; j >= 0; --j) + if (cnt[j]) { + update(j, bord, bord + cnt[j] - 1, 1); + bord += cnt[j]; + } } + + fill(all(cnt), 0); } - - fill(all(cnt), 0); - } - - string ans(N, '-'); - for (int j = 0; j < 26; ++j) - get_ans(j, ans); - cout << ans << ende; - return 0; + + string ans(N, '-'); + for (int j = 0; j < 26; ++j) + get_ans(j, ans); + cout << ans << ende; + return 0; } diff --git a/problems/crise_hidrica.cpp b/problems/crise_hidrica.cpp index 308fc2f350a3bce00f954c5fc4150fb7ce54de1d..7519193ee72b53cd0c3f6ca9cd59a7cbd9d4517f 100644 --- a/problems/crise_hidrica.cpp +++ b/problems/crise_hidrica.cpp @@ -34,106 +34,106 @@ int par[MAX][MAXLOG]; ll upd[MAX]; void dfs(int va, int p = -1) { - par[va][0] = p; + par[va][0] = p; - if (p + 1) - h[va] = h[p] + 1; + if (p + 1) + h[va] = h[p] + 1; - for (int i = 1; i < MAXLOG; ++i) - if (par[va][i - 1] + 1) - par[va][i] = par[par[va][i - 1]][i - 1]; + for (int i = 1; i < MAXLOG; ++i) + if (par[va][i - 1] + 1) + par[va][i] = par[par[va][i - 1]][i - 1]; - for (auto u : graph[va]) - if (p != u) - dfs(u, va); + for (auto u : graph[va]) + if (p != u) + dfs(u, va); } void preprocess(int va) { - memset(par, -1, sizeof par); - dfs(va); + memset(par, -1, sizeof par); + dfs(va); } int query(int p, int q) { - if (h[p] < h[q]) - swap(p, q); + if (h[p] < h[q]) + swap(p, q); - for (int i = MAXLOG - 1; i >= 0; --i) - if (par[p][i] + 1 && h[par[p][i]] >= h[q]) { - p = par[p][i]; - } + for (int i = MAXLOG - 1; i >= 0; --i) + if (par[p][i] + 1 && h[par[p][i]] >= h[q]) { + p = par[p][i]; + } - if (p == q) - return p; + if (p == q) + return p; - for (int i = MAXLOG - 1; i >= 0; --i) - if (par[p][i] + 1 && par[p][i] != par[q][i]) { - p = par[p][i]; - q = par[q][i]; - } + for (int i = MAXLOG - 1; i >= 0; --i) + if (par[p][i] + 1 && par[p][i] != par[q][i]) { + p = par[p][i]; + q = par[q][i]; + } - return par[p][0]; + return par[p][0]; } ll fill(int x, int pare) { - ll ans = 0; + ll ans = 0; - for (auto i : graph[x]) - if (i != pare) - ans += fill(i, x); + for (auto i : graph[x]) + if (i != pare) + ans += fill(i, x); - return v[x] = ans + upd[x]; + return v[x] = ans + upd[x]; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, d, a, b; - cin >> n >> d; - for (int i = 0; i < n - 1; ++i) { - cin >> a >> b; - graph[a].pb(b); - graph[b].pb(a); - } - - int m, vv, c; - cin >> m; - vector<int> w(m+1), avail; - for (int i = 0; i < m; ++i) { - cin >> c >> vv; - w[i+1] = vv; - avail.pb(c); - } - - preprocess(1); - - ll q, l; - int x, y; - cin >> q; - for (int i = 0; i < q; ++i) { - cin >> x >> y >> l; - int lca = query(x, y); - - upd[lca] -= l; - upd[x] += l; - upd[y] += l; - if (lca != 1) - upd[par[lca][0]] -= l; - } - - fill(1, -1); - - vector<ll> vvv(m+1); - for (int i = 0; i < m; ++i) - vvv[i+1] = v[avail[i]]; - - for (int i = 1; i <= m; ++i) - for (int j = 0; j <= d; ++j) - if (j >= w[i]) - dp[i][j] = max(dp[i-1][j], dp[i-1][j - w[i]] + vvv[i]); - else - dp[i][j] = dp[i-1][j]; - - cout << dp[m][d] << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int n, d, a, b; + cin >> n >> d; + for (int i = 0; i < n - 1; ++i) { + cin >> a >> b; + graph[a].pb(b); + graph[b].pb(a); + } + + int m, vv, c; + cin >> m; + vector<int> w(m+1), avail; + for (int i = 0; i < m; ++i) { + cin >> c >> vv; + w[i+1] = vv; + avail.pb(c); + } + + preprocess(1); + + ll q, l; + int x, y; + cin >> q; + for (int i = 0; i < q; ++i) { + cin >> x >> y >> l; + int lca = query(x, y); + + upd[lca] -= l; + upd[x] += l; + upd[y] += l; + if (lca != 1) + upd[par[lca][0]] -= l; + } + + fill(1, -1); + + vector<ll> vvv(m+1); + for (int i = 0; i < m; ++i) + vvv[i+1] = v[avail[i]]; + + for (int i = 1; i <= m; ++i) + for (int j = 0; j <= d; ++j) + if (j >= w[i]) + dp[i][j] = max(dp[i-1][j], dp[i-1][j - w[i]] + vvv[i]); + else + dp[i][j] = dp[i-1][j]; + + cout << dp[m][d] << ende; + return 0; } diff --git a/problems/escalacao.cpp b/problems/escalacao.cpp index 67d71df38fc383a32059447701b31b481584e809..c8c5ccfc23a2eb698327cd1f7480df4e3ad4ba3e 100644 --- a/problems/escalacao.cpp +++ b/problems/escalacao.cpp @@ -29,78 +29,78 @@ vector<ll> tree[MAX]; vector<ll> res; void merge(vector<ll> a, vector<ll> b, vector<ll> &ans) { - int i = 0, j = 0, cnt = 0; - for ( ; cnt < k && i < a.size() && j < b.size(); ++cnt) - if (a[i] > b[j]) - ans.push_back(a[i++]); - else - ans.push_back(b[j++]); - - if (cnt < k) { - if (i < a.size()) - for (; cnt < k && i < a.size(); ++i, ++cnt) - ans.push_back(a[i]); - else - for (; cnt < k && j < b.size(); ++j, ++cnt) - ans.push_back(b[j]); - } + int i = 0, j = 0, cnt = 0; + for ( ; cnt < k && i < a.size() && j < b.size(); ++cnt) + if (a[i] > b[j]) + ans.push_back(a[i++]); + else + ans.push_back(b[j++]); + + if (cnt < k) { + if (i < a.size()) + for (; cnt < k && i < a.size(); ++i, ++cnt) + ans.push_back(a[i]); + else + for (; cnt < k && j < b.size(); ++j, ++cnt) + ans.push_back(b[j]); + } } void build(int node = 1, int a = 0, int b = n - 1) { - if (a > b) - return; - if (a == b) { - tree[node].push_back(v[a]); - return; - } - - build(node * 2, a, (a + b) / 2); - build(node * 2 + 1, 1 + (a + b) / 2, b); - merge(tree[node * 2], tree[node * 2 + 1], tree[node]); + if (a > b) + return; + if (a == b) { + tree[node].push_back(v[a]); + return; + } + + build(node * 2, a, (a + b) / 2); + build(node * 2 + 1, 1 + (a + b) / 2, b); + merge(tree[node * 2], tree[node * 2 + 1], tree[node]); } void query(int i, int j, int node = 1, int a = 0, int b = n - 1) { - if (a > b || a > j || b < i) - return; - if (a >= i && b <= j) { - res.insert(res.end(), tree[node].begin(), tree[node].end()); - return; - } - - query(i, j, node * 2, a, (a + b) / 2); - query(i, j, 1 + node * 2, 1 + (a + b) / 2, b); + if (a > b || a > j || b < i) + return; + if (a >= i && b <= j) { + res.insert(res.end(), tree[node].begin(), tree[node].end()); + return; + } + + query(i, j, node * 2, a, (a + b) / 2); + query(i, j, 1 + node * 2, 1 + (a + b) / 2, b); } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - cin >> n >> k >> r; - for (int i = 0; i < n; ++i) - cin >> v[i]; - build(); - - for (int i = 0; i < r; ++i) { - int ans = 1; - res.clear(); - ll a, b; cin >> a >> b; - query(a - 1, b - 1); - - sort(res.begin(), res.end()); - - int cnt = 0; - for (int j = res.size() - 1; j >= 0; --j) { - if (cnt >= k || res[j] == 0) { - if (res[j] == 0 && j == res.size() - 1) - ans = 0; - break; - } - ans = (ans * res[j]) % MOD; - cnt++; + ios::sync_with_stdio(0); + cin.tie(0); + + cin >> n >> k >> r; + for (int i = 0; i < n; ++i) + cin >> v[i]; + build(); + + for (int i = 0; i < r; ++i) { + int ans = 1; + res.clear(); + ll a, b; cin >> a >> b; + query(a - 1, b - 1); + + sort(res.begin(), res.end()); + + int cnt = 0; + for (int j = res.size() - 1; j >= 0; --j) { + if (cnt >= k || res[j] == 0) { + if (res[j] == 0 && j == res.size() - 1) + ans = 0; + break; + } + ans = (ans * res[j]) % MOD; + cnt++; + } + + cout << ans << ende; } - cout << ans << ende; - } - - return 0; + return 0; } diff --git a/problems/exponial.cpp b/problems/exponial.cpp index 8eb98af9b7c806b4d114bf9d4ad63d03f8500441..bc3e4ba76ab27d70ba0230b04919b7e9d55ca4b0 100644 --- a/problems/exponial.cpp +++ b/problems/exponial.cpp @@ -22,59 +22,59 @@ using ll = long long; using ii = pair<int,int>; ll phi(ll n) { - ll result = n; + ll result = n; - for (ll i = 2; i*i <= n; i++) { - if (n % i == 0) { - while (n % i == 0) n /= i; - result -= result / i; + for (ll i = 2; i*i <= n; i++) { + if (n % i == 0) { + while (n % i == 0) n /= i; + result -= result / i; + } } - } - if (n > 1) - result -= result / n; + if (n > 1) + result -= result / n; - return result; + return result; } ll fast_pow(ll x, ll n, ll m) { - ll ans = 1; + ll ans = 1; - while (n) { - if (n & 1) - ans = (ans * x) % m; + while (n) { + if (n & 1) + ans = (ans * x) % m; - n >>= 1; - x = (x * x) % m; - } + n >>= 1; + x = (x * x) % m; + } - return ans % m; + return ans % m; } ll solve(ll n, ll m) { - if (m == 1) - return 0; + if (m == 1) + return 0; + + if (n <= 5) { + if (n == 4) return 262144 % m; + else if (n == 3) return 9 % m; + else if (n == 2) return 2 % m; + else if (n == 1) return 1 % m; + else return fast_pow(5, 262144, m); + } - if (n <= 5) { - if (n == 4) return 262144 % m; - else if (n == 3) return 9 % m; - else if (n == 2) return 2 % m; - else if (n == 1) return 1 % m; - else return fast_pow(5, 262144, m); - } - - // n^e % m == n^(phi(m) + e % phi(m)) mod m - ll p = phi(m); - ll e = p + solve(n - 1, p) % p; - return fast_pow(n, e, m); + // n^e % m == n^(phi(m) + e % phi(m)) mod m + ll p = phi(m); + ll e = p + solve(n - 1, p) % p; + return fast_pow(n, e, m); } int main() { - ios::sync_with_stdio(0); - cin.tie(0); + ios::sync_with_stdio(0); + cin.tie(0); - ll n, m; cin >> n >> m; - cout << solve(n, m) << ende; + ll n, m; cin >> n >> m; + cout << solve(n, m) << ende; - return 0; + return 0; } diff --git a/problems/trees_partition.cpp b/problems/trees_partition.cpp index e7aaf7944c265c34ab647e7817cc133350977b2c..48374d8a965bad8ab8731340e9e488fa794939ec 100644 --- a/problems/trees_partition.cpp +++ b/problems/trees_partition.cpp @@ -26,65 +26,65 @@ unordered_map<ll, int> M; ll ans = 0, tot = 0; ll dfs(int x, int par) { - ll down = hsh[x]; - - for (auto i : t1[x]) { - if (i != par) { - ll bel = dfs(i, x); - down ^= bel; - M[bel] = 1; + ll down = hsh[x]; + + for (auto i : t1[x]) { + if (i != par) { + ll bel = dfs(i, x); + down ^= bel; + M[bel] = 1; + } } - } - return down; + return down; } ll solve(int x, int par) { - ll down = hsh[x]; - - for (auto i : t2[x]) { - if (i != par) { - ll bel = solve(i, x); - down ^= bel; - - if (M[bel] || M[bel ^ tot]) { - ans++; - M[bel] = M[bel ^ tot] = 0; - } + ll down = hsh[x]; + + for (auto i : t2[x]) { + if (i != par) { + ll bel = solve(i, x); + down ^= bel; + + if (M[bel] || M[bel ^ tot]) { + ans++; + M[bel] = M[bel ^ tot] = 0; + } + } } - } - return down; + return down; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - int n, x; - cin >> n; - mt19937_64 mt(time(NULL)); - - for (int i = 0; i < n - 1; ++i) { - cin >> x; - t1[i+1].pb(x-1); - t1[x-1].pb(i+1); - } - - for (int i = 0; i < n - 1; ++i) { - cin >> x; - t2[i+1].pb(x-1); - t2[x-1].pb(i+1); - } - - for (int i = 0; i < n; ++i) { - hsh[i] = mt(); - tot ^= hsh[i]; - } - - dfs(0, -1); - solve(0, -1); - - cout << ans << '\n'; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + int n, x; + cin >> n; + mt19937_64 mt(time(NULL)); + + for (int i = 0; i < n - 1; ++i) { + cin >> x; + t1[i+1].pb(x-1); + t1[x-1].pb(i+1); + } + + for (int i = 0; i < n - 1; ++i) { + cin >> x; + t2[i+1].pb(x-1); + t2[x-1].pb(i+1); + } + + for (int i = 0; i < n; ++i) { + hsh[i] = mt(); + tot ^= hsh[i]; + } + + dfs(0, -1); + solve(0, -1); + + cout << ans << '\n'; + return 0; } diff --git a/problems/xor_submatrix.cpp b/problems/xor_submatrix.cpp index 70afff0d2780220c13372984f091302d7ac59ec6..54323e1ea6a45624ff6b86d063b7856cc547dcfc 100644 --- a/problems/xor_submatrix.cpp +++ b/problems/xor_submatrix.cpp @@ -27,69 +27,69 @@ int states = 0; int trie[MAX][2]; void insert(int x) { - int node = 0; + int node = 0; - for (int i = 30; i >= 0; --i) { - int b = !!(x & (1 << i)); + for (int i = 30; i >= 0; --i) { + int b = !!(x & (1 << i)); - if (trie[node][b] == -1) - trie[node][b] = ++states; - node = trie[node][b]; - } + if (trie[node][b] == -1) + trie[node][b] = ++states; + node = trie[node][b]; + } } int search(int x) { - int node = 0; - int ans = 0; - - for (int i = 30; i >= 0; --i) { - int b = !(x & (1 << i)); + int node = 0; + int ans = 0; - if (trie[node][b] == -1) - b ^= 1; + for (int i = 30; i >= 0; --i) { + int b = !(x & (1 << i)); - node = trie[node][b]; - ans |= (b << i); - } + if (trie[node][b] == -1) + b ^= 1; - return ans; + node = trie[node][b]; + ans |= (b << i); + } + + return ans; } int main() { - ios::sync_with_stdio(0); - cin.tie(0); - - mset(trie, -1); - - int n, m; cin >> n >> m; - vector<int> v(n+1), u(m+1); - - v[0] = u[0] = 0; - for (int i = 1; i <= n; ++i) { - int x; cin >> x; - v[i] = v[i-1] ^ x; - } - - for (int i = 1; i <= m; ++i) { - int x; cin >> x; - u[i] = u[i-1] ^ x; - } - - int ans = 0; - for (int i = 0; i <= n; ++i) - for (int j = i; j <= n; ++j) - if ((j - i) % 2) - insert(v[i] ^ v[j]); - else - ans = max(ans, v[i] ^ v[j]); - - for (int i = 0; i <= m; ++i) - for (int j = i; j <= m; ++j) - if ((j - i) % 2) - ans = max(ans, u[i] ^ u[j] ^ search(u[i] ^ u[j])); - else - ans = max(ans, u[i] ^ u[j]); - - cout << ans << ende; - return 0; + ios::sync_with_stdio(0); + cin.tie(0); + + mset(trie, -1); + + int n, m; cin >> n >> m; + vector<int> v(n+1), u(m+1); + + v[0] = u[0] = 0; + for (int i = 1; i <= n; ++i) { + int x; cin >> x; + v[i] = v[i-1] ^ x; + } + + for (int i = 1; i <= m; ++i) { + int x; cin >> x; + u[i] = u[i-1] ^ x; + } + + int ans = 0; + for (int i = 0; i <= n; ++i) + for (int j = i; j <= n; ++j) + if ((j - i) % 2) + insert(v[i] ^ v[j]); + else + ans = max(ans, v[i] ^ v[j]); + + for (int i = 0; i <= m; ++i) + for (int j = i; j <= m; ++j) + if ((j - i) % 2) + ans = max(ans, u[i] ^ u[j] ^ search(u[i] ^ u[j])); + else + ans = max(ans, u[i] ^ u[j]); + + cout << ans << ende; + return 0; }