diff --git a/algorithms/geometry/rotating_calipers.cpp b/algorithms/geometry/rotating_calipers.cpp new file mode 100644 index 0000000000000000000000000000000000000000..65fd15e4be3d9a095863e87101ebc814bc2f8b9f --- /dev/null +++ b/algorithms/geometry/rotating_calipers.cpp @@ -0,0 +1,41 @@ +/// Rotating Calipers +/// +/// Time: O(n log n) +/// Space: O(n) + +double dist(point a, point b) { + return hypot(a.fi - b.fi, a.se - b.se); +} + +double area(point a, point b, point c) { + return abs((b.fi - a.fi) * (c.se - a.se) - \ + (b.se - a.se) * (c.fi - a.fi)); +} + +double diameter(vector<point> &v) { + vector<point> h = convex_hull(v); + + int m = h.size(); + if (m == 1) return 0; + if (m == 2) return dist(h[0], h[1]); + + int k = 1; + while (area(h[m-1], h[0], h[(k+1)%m]) > + area(h[m-1], h[0], h[k])) + k++; + + double ans = 0; + for (int i = 0, j = k; i <= k && j < m; ++i) { + ans = max(ans, dist(h[i], h[j])); + + while (i < m && + area(h[i], h[(i+1)%m], h[(j+1)%m]) > + area(h[i], h[(i+1)%m], h[j])) + { + ans = max(ans, dist(h[i], h[(j+1)%m])); + j++; + } + } + + return ans; +} diff --git a/algorithms/graph/hld.cpp b/algorithms/graph/hld.cpp new file mode 100644 index 0000000000000000000000000000000000000000..777dc7b334643633963c77ad3dce1ef87a077837 --- /dev/null +++ b/algorithms/graph/hld.cpp @@ -0,0 +1,141 @@ +/// Heavy Light Decomposition +/// +/// Time: +/// - build: O(n log n) +/// - query: O(log^2 n) +/// - update: O(log n) +/// Space: O(n log n) + +#define LOG 20 // log2(MAX) + +ii edge[MAX]; +int par[MAX][LOG]; +vector<ii> graph[MAX]; + +template <typename ST> +struct HLD { + ST &seg; + int cnum, ptr; + + // Size of subtree, and depth + vector<int> size, dep; + + // Chain's head, chain's index, base array for segtree, + // position of node in base, and bottommost node + vector<int> chead, cidx, base, pos, bot; + + HLD(int n, ST &seg) : + seg(seg), size(n), dep(n, 0), bot(n), + chead(n, -1), cidx(n), base(n), pos(n) + { + mset(par, -1); + cnum = ptr = 0; + + dfs(0); + decompose(0); + + N = ptr; // global N for segtree + seg.build(base); + + // bot[i] stores the bottommost (depth-wise) node + // on the i-th edge + 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; + } + + void dfs(int x, int p = -1) { + size[x] = 1; + par[x][0] = p; + + for (int i = 1; i < LOG; ++i) + if (par[x][i - 1] != -1) + par[x][i] = par[par[x][i - 1]][i - 1]; + + for (auto i : graph[x]) + if (i.fi != p) { + dep[i.fi] = dep[x] + 1; + dfs(i.fi, x); + size[x] += size[i.fi]; + } + } + + void decompose(int x, int c = -1, int p = -1) { + if (chead[cnum] == -1) + chead[cnum] = x; + + pos[x] = ptr; + cidx[x] = cnum; + base[ptr++] = c; + + ii sc(-1, -1); + if (graph[x].size() > 1) { + for (auto i : graph[x]) + if (i.fi != p) + if (sc.fi == -1 || size[sc.fi] < size[i.fi]) + sc = i; + + decompose(sc.fi, sc.se, x); + } + + for (auto i : graph[x]) + if (sc.fi != i.fi && i.fi != p) { + cnum++; + decompose(i.fi, i.se, x); + } + } + + int query_up(int a, int b) { + if (a == b) return 0; + + int ca, cb = cidx[b], ans = -1; + while (1) { + ca = cidx[a]; + if (ca == cb) { + if (a == b) break; + ans = max(ans, seg.query(pos[b] + 1, pos[a])); + break; + } + + ans = max(ans, seg.query(pos[chead[ca]], pos[a])); + a = par[chead[ca]][0]; + } + + return ans; + } + + int lca(int a, int b) { + int ans = 0; + + if (dep[a] < dep[b]) + swap(a, b); + + for (int i = LOG - 1; i >= 0; --i) + if (par[a][i] != -1 && dep[par[a][i]] >= dep[b]) + a = par[a][i]; + + if (a == b) + return a; + + for (int i = LOG - 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]; + } + + // Queries max edge on the path between a and b + int query(int a, int b) { + int lab = lca(a, b); + return max(query_up(a, lab), query_up(b, lab)); + } + + // Updates value of i-th edge + void update(int i, int val) { + seg.update(pos[bot[i]], val); + } +}; diff --git a/algorithms/graph/lca.cpp b/algorithms/graph/lca.cpp index a0efdf7c396c2218e7ca56ce806176a38bfe6a13..51bd1cf3940cd655f36684e2568803882c973cb4 100644 --- a/algorithms/graph/lca.cpp +++ b/algorithms/graph/lca.cpp @@ -17,24 +17,21 @@ /// - query: O(log V) /// Space: O(V + E + V log V) -#define MAXLOG 20 //log2(MAX) +#define LOG 20 // log2(MAX) vector<ii> graph[MAX]; +int par[MAX][LOG], cost[MAX][LOG]; 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)) + LCA(int N) : h(N) { init(); } void init() { - for (auto &i : par) fill(all(i), -1); - for (auto &i : cost) fill(all(i), 0); - dfs(0); // 0-indexed vertices + mset(par, -1); + mset(cost, 0); + dfs(0); // root is 0 } int op(int a, int b) { @@ -48,7 +45,7 @@ struct LCA { if (p != -1) h[v] = h[p] + 1; - for (int i = 1; i < MAXLOG; ++i) + 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] = op(cost[v][i], op(cost[v][i-1], @@ -66,7 +63,7 @@ struct LCA { if (h[a] < h[b]) swap(a, b); - for (int i = MAXLOG - 1; i >= 0; --i) + for (int i = LOG - 1; i >= 0; --i) if (par[a][i] != -1 && h[par[a][i]] >= h[b]) { ans = op(ans, cost[a][i]); a = par[a][i]; @@ -80,7 +77,7 @@ struct LCA { #endif } - for (int i = MAXLOG - 1; i >= 0; --i) + for (int i = LOG - 1; i >= 0; --i) if (par[a][i] != -1 && par[a][i] != par[b][i]) { ans = op(ans, op(cost[a][i], cost[b][i])); a = par[a][i]; diff --git a/algorithms/structure/lazy_segment_tree.cpp b/algorithms/structure/lazy_segment_tree.cpp index b3d95f7b24783f26f25bcce8820947fc55d02c1e..e2d45decd5e5c917ffed8fc205a42954b8ff7bde 100644 --- a/algorithms/structure/lazy_segment_tree.cpp +++ b/algorithms/structure/lazy_segment_tree.cpp @@ -5,6 +5,10 @@ /// - update: O(log n) /// - query: O(log n) /// Space: O(n) +/// +/// Caution: +/// - Provide value for N before any operation +/// - Provide identity value if necessary (default is T()) #define left(x) (x << 1) #define right(x) ((x << 1) + 1) @@ -15,14 +19,12 @@ template <typename T> struct LazySegmentTree { using func = function<T(T,T)>; - T id; func op; + T id = T(); vector<T> tree, lazy; - LazySegmentTree(vector<T> &v, func op, T id=T()) : - tree(MAX*4, 0), lazy(MAX*4, 0), - op(op), id(id) - { build(v); } + LazySegmentTree(func op) : + op(op), tree(MAX*4, 0), lazy(MAX*4, 0) {} void build(const vector<T> &v, int node = 1, int l = 0, int r = N - 1) diff --git a/algorithms/structure/segment_tree.cpp b/algorithms/structure/segment_tree.cpp index c62f76d289f6816ae519d699fe4dbf062505b514..50727c5142881ff093d53b7881ef0b70efb59f44 100644 --- a/algorithms/structure/segment_tree.cpp +++ b/algorithms/structure/segment_tree.cpp @@ -6,33 +6,69 @@ /// Space: O(n) /// /// Caution: -/// - Query returns $op([l,r))$ +/// - Provide value for N before any operation /// - Provide identity value if necessary (default is T()) +#define left(x) (x << 1) +#define right(x) ((x << 1) + 1) + +int N; + template <typename T> struct SegmentTree { using func = function<T(T,T)>; - T id; - int N; func op; + T ident = T(); vector<T> tree; - SegmentTree(int N, func op, T id = T()) : - N(N), op(op), id(id), tree(2*N, id) {} + 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; - void update(int idx, T val) { - tree[idx + N] = val; - for (idx += N; idx > 1; idx/=2) - tree[idx/2] = op(tree[idx & ~1], tree[idx | 1]); + 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)]); + } } - T query(int l, int r) { - T ans = id; - for (l += N, r += N ; l < r; l/=2, r/=2) { - if (l & 1) ans = op(ans, tree[l++]); - if (r & 1) ans = op(ans, tree[--r]); + 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)]); } - return ans; + } + + 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); } }; diff --git a/contests/Cadernaveis/LA5138.cpp b/contests/Cadernaveis/LA5138.cpp new file mode 100644 index 0000000000000000000000000000000000000000..732fc821607a493dc747cfe1b6195c1ac0295675 --- /dev/null +++ b/contests/Cadernaveis/LA5138.cpp @@ -0,0 +1,95 @@ +#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>; + +using point = pair<double,double>; + +bool cw(point a, point b, point c) { + return (b.fi - a.fi) * (c.se - a.se) - \ + (b.se - a.se) * (c.fi - a.fi) <= 0; +} + +//double cross(point a, point b, point c) { +// return (b.fi - a.fi) * (c.se - a.se) - \ +// (b.se - a.se) * (c.fi - a.fi); +//} +double cross(const point &o, const point &a, const point &b) { + return (a.fi - o.fi) * (b.se - o.se) - (a.se - o.se) * (b.fi - o.fi); +} + +vector<point> convex_hull(vector<point> &v) { + int k = 0; + vector<point> ans(v.size() * 2); + + sort(all(v), [](const point &a, const point &b) { + return (a.fi == b.fi) ? (a.se < b.se) : (a.fi < b.fi); + }); + + 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]; + } + + ans.resize(k); + return ans; +} + +double dist_line(point p, point a, point b) { + return cross(b, a, p) / sqrt((b.se-a.se) * (b.se-a.se) + (b.fi-a.fi)*(b.fi-a.fi)); +} + +double width(vector<point> &v) { + vector<point> h = convex_hull(v); + int n = h.size() - 1; + int j = 1; + + double ans = 1e14; + h[0] = h[n]; + for (int i = 1; i <= n; ++i) { + while (cross(h[i-1], h[i], h[j%n+1]) > cross(h[i-1], h[i], h[j])) + j = j % n + 1; + ans = min(ans, dist_line(h[j], h[i], h[i-1])); + } + + return ceil(ans*100)/100; +} + +int main() { + 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].fi >> v[i].se; + + cout << "Case " << cas << ": " << width(v) << ende; + cas++; + } + + return 0; +} diff --git a/contests/Cadernaveis/a.out b/contests/Cadernaveis/a.out new file mode 100755 index 0000000000000000000000000000000000000000..4768325f00306911ab20830aec41303b7e9a1c5e Binary files /dev/null and b/contests/Cadernaveis/a.out differ diff --git a/contests/Cadernaveis/in b/contests/Cadernaveis/in new file mode 100644 index 0000000000000000000000000000000000000000..1f16e897b84c4216725031b8d271dea91b14b050 --- /dev/null +++ b/contests/Cadernaveis/in @@ -0,0 +1,10 @@ +3 +0 0 +3 0 +0 4 +4 +0 10 +10 0 +20 10 +10 20 +0 diff --git a/contests/Cadernaveis/out b/contests/Cadernaveis/out new file mode 100644 index 0000000000000000000000000000000000000000..6552e7d68b41fea92faba0e132cf10b40c394e32 --- /dev/null +++ b/contests/Cadernaveis/out @@ -0,0 +1,369 @@ +Case 1: 2.40 +Case 2: 14.15 +Case 3: 0.71 +Case 4: 0.71 +Case 5: 0.71 +Case 6: 0.71 +Case 7: 0.71 +Case 8: 0.71 +Case 9: 0.01 +Case 10: 0.01 +Case 11: 0.01 +Case 12: 0.01 +Case 13: 0.01 +Case 14: 0.01 +Case 15: 10000.00 +Case 16: 26.00 +Case 17: 26.00 +Case 18: 26.00 +Case 19: 26.00 +Case 20: 26.00 +Case 21: 26.00 +Case 22: 2.00 +Case 23: 2.00 +Case 24: 2.00 +Case 25: 2.00 +Case 26: 2.00 +Case 27: 2.00 +Case 28: 26.00 +Case 29: 26.00 +Case 30: 26.00 +Case 31: 26.00 +Case 32: 26.00 +Case 33: 26.00 +Case 34: 421.90 +Case 35: 421.90 +Case 36: 421.90 +Case 37: 421.90 +Case 38: 421.90 +Case 39: 421.90 +Case 40: 313.62 +Case 41: 313.62 +Case 42: 313.62 +Case 43: 313.62 +Case 44: 313.62 +Case 45: 313.62 +Case 46: 739.83 +Case 47: 739.83 +Case 48: 739.83 +Case 49: 739.83 +Case 50: 739.83 +Case 51: 739.83 +Case 52: 939.89 +Case 53: 939.89 +Case 54: 939.89 +Case 55: 939.89 +Case 56: 939.89 +Case 57: 939.89 +Case 58: 943.66 +Case 59: 943.66 +Case 60: 943.66 +Case 61: 943.66 +Case 62: 943.66 +Case 63: 943.66 +Case 64: 965.95 +Case 65: 965.95 +Case 66: 965.95 +Case 67: 965.95 +Case 68: 965.95 +Case 69: 965.95 +Case 70: 941.45 +Case 71: 941.45 +Case 72: 941.45 +Case 73: 941.45 +Case 74: 941.45 +Case 75: 941.45 +Case 76: 827.61 +Case 77: 827.61 +Case 78: 827.61 +Case 79: 827.61 +Case 80: 827.61 +Case 81: 827.61 +Case 82: 962.07 +Case 83: 962.07 +Case 84: 962.07 +Case 85: 962.07 +Case 86: 962.07 +Case 87: 962.07 +Case 88: 522.79 +Case 89: 522.79 +Case 90: 522.79 +Case 91: 522.79 +Case 92: 522.79 +Case 93: 522.79 +Case 94: 868.59 +Case 95: 868.59 +Case 96: 868.59 +Case 97: 868.59 +Case 98: 868.59 +Case 99: 868.59 +Case 100: 943.42 +Case 101: 943.42 +Case 102: 943.42 +Case 103: 943.42 +Case 104: 943.42 +Case 105: 943.42 +Case 106: 849.02 +Case 107: 849.02 +Case 108: 849.02 +Case 109: 849.02 +Case 110: 849.02 +Case 111: 849.02 +Case 112: 872.17 +Case 113: 872.17 +Case 114: 872.17 +Case 115: 872.17 +Case 116: 872.17 +Case 117: 872.17 +Case 118: 918.82 +Case 119: 918.82 +Case 120: 918.82 +Case 121: 918.82 +Case 122: 918.82 +Case 123: 918.82 +Case 124: 830.42 +Case 125: 830.42 +Case 126: 830.42 +Case 127: 830.42 +Case 128: 830.42 +Case 129: 830.42 +Case 130: 887.99 +Case 131: 887.99 +Case 132: 887.99 +Case 133: 887.99 +Case 134: 887.99 +Case 135: 887.99 +Case 136: 819.72 +Case 137: 819.72 +Case 138: 819.72 +Case 139: 819.72 +Case 140: 819.72 +Case 141: 819.72 +Case 142: 916.86 +Case 143: 916.86 +Case 144: 916.86 +Case 145: 916.86 +Case 146: 916.86 +Case 147: 916.86 +Case 148: 894.85 +Case 149: 894.85 +Case 150: 894.85 +Case 151: 894.85 +Case 152: 894.85 +Case 153: 894.85 +Case 154: 907.85 +Case 155: 907.85 +Case 156: 907.85 +Case 157: 907.85 +Case 158: 907.85 +Case 159: 907.85 +Case 160: 897.52 +Case 161: 897.52 +Case 162: 897.52 +Case 163: 897.52 +Case 164: 897.52 +Case 165: 897.52 +Case 166: 698.88 +Case 167: 698.88 +Case 168: 698.88 +Case 169: 698.88 +Case 170: 698.88 +Case 171: 698.88 +Case 172: 520.04 +Case 173: 520.04 +Case 174: 520.04 +Case 175: 520.04 +Case 176: 520.04 +Case 177: 520.04 +Case 178: 948.53 +Case 179: 948.53 +Case 180: 948.53 +Case 181: 948.53 +Case 182: 948.53 +Case 183: 948.53 +Case 184: 890.01 +Case 185: 890.01 +Case 186: 890.01 +Case 187: 890.01 +Case 188: 890.01 +Case 189: 890.01 +Case 190: 863.93 +Case 191: 863.93 +Case 192: 863.93 +Case 193: 863.93 +Case 194: 863.93 +Case 195: 863.93 +Case 196: 902.07 +Case 197: 902.07 +Case 198: 902.07 +Case 199: 902.07 +Case 200: 902.07 +Case 201: 902.07 +Case 202: 841.60 +Case 203: 841.60 +Case 204: 841.60 +Case 205: 841.60 +Case 206: 841.60 +Case 207: 841.60 +Case 208: 887.03 +Case 209: 887.03 +Case 210: 887.03 +Case 211: 887.03 +Case 212: 887.03 +Case 213: 887.03 +Case 214: 677.03 +Case 215: 677.03 +Case 216: 677.03 +Case 217: 677.03 +Case 218: 677.03 +Case 219: 677.03 +Case 220: 917.60 +Case 221: 917.60 +Case 222: 917.60 +Case 223: 917.60 +Case 224: 917.60 +Case 225: 917.60 +Case 226: 699.30 +Case 227: 699.30 +Case 228: 699.30 +Case 229: 699.30 +Case 230: 699.30 +Case 231: 699.30 +Case 232: 781.85 +Case 233: 781.85 +Case 234: 781.85 +Case 235: 781.85 +Case 236: 781.85 +Case 237: 781.85 +Case 238: 635.53 +Case 239: 635.53 +Case 240: 635.53 +Case 241: 635.53 +Case 242: 635.53 +Case 243: 635.53 +Case 244: 846.09 +Case 245: 846.09 +Case 246: 846.09 +Case 247: 846.09 +Case 248: 846.09 +Case 249: 846.09 +Case 250: 553.25 +Case 251: 553.25 +Case 252: 553.25 +Case 253: 553.25 +Case 254: 553.25 +Case 255: 553.25 +Case 256: 971.14 +Case 257: 971.14 +Case 258: 971.14 +Case 259: 971.14 +Case 260: 971.14 +Case 261: 971.14 +Case 262: 834.71 +Case 263: 834.71 +Case 264: 834.71 +Case 265: 834.71 +Case 266: 834.71 +Case 267: 834.71 +Case 268: 857.93 +Case 269: 857.93 +Case 270: 857.93 +Case 271: 857.93 +Case 272: 857.93 +Case 273: 857.93 +Case 274: 929.54 +Case 275: 929.54 +Case 276: 929.54 +Case 277: 929.54 +Case 278: 929.54 +Case 279: 929.54 +Case 280: 882.55 +Case 281: 882.55 +Case 282: 882.55 +Case 283: 882.55 +Case 284: 882.55 +Case 285: 882.55 +Case 286: 920.93 +Case 287: 920.93 +Case 288: 920.93 +Case 289: 920.93 +Case 290: 920.93 +Case 291: 920.93 +Case 292: 885.83 +Case 293: 885.83 +Case 294: 885.83 +Case 295: 885.83 +Case 296: 885.83 +Case 297: 885.83 +Case 298: 969.79 +Case 299: 969.79 +Case 300: 969.79 +Case 301: 969.79 +Case 302: 969.79 +Case 303: 969.79 +Case 304: 935.10 +Case 305: 935.10 +Case 306: 935.10 +Case 307: 935.10 +Case 308: 935.10 +Case 309: 935.10 +Case 310: 821.22 +Case 311: 821.22 +Case 312: 821.22 +Case 313: 821.22 +Case 314: 821.22 +Case 315: 821.22 +Case 316: 936.47 +Case 317: 936.47 +Case 318: 936.47 +Case 319: 936.47 +Case 320: 936.47 +Case 321: 936.47 +Case 322: 669.83 +Case 323: 669.83 +Case 324: 669.83 +Case 325: 669.83 +Case 326: 669.83 +Case 327: 669.83 +Case 328: 937.78 +Case 329: 937.78 +Case 330: 937.78 +Case 331: 937.78 +Case 332: 937.78 +Case 333: 937.78 +Case 334: 911.71 +Case 335: 911.71 +Case 336: 911.71 +Case 337: 911.71 +Case 338: 911.71 +Case 339: 911.71 +Case 340: 878.29 +Case 341: 878.29 +Case 342: 878.29 +Case 343: 878.29 +Case 344: 878.29 +Case 345: 878.29 +Case 346: 911.88 +Case 347: 911.88 +Case 348: 911.88 +Case 349: 911.88 +Case 350: 911.88 +Case 351: 911.88 +Case 352: 819.50 +Case 353: 819.50 +Case 354: 819.50 +Case 355: 819.50 +Case 356: 819.50 +Case 357: 819.50 +Case 358: 914.16 +Case 359: 914.16 +Case 360: 914.16 +Case 361: 914.16 +Case 362: 914.16 +Case 363: 914.16 +Case 364: 525.55 +Case 365: 525.55 +Case 366: 525.55 +Case 367: 525.55 +Case 368: 525.55 +Case 369: 525.55