From 48a13b9262e03b566d2c74fe15ea5430896e0d95 Mon Sep 17 00:00:00 2001 From: Segcolt <9hmbzr275@mozmail.com> Date: Thu, 24 Oct 2024 14:45:14 -0300 Subject: [PATCH] Finish this hellish problem Holy crap... Memory limit gallore, I had to make a LOT of optimizations on this one, and it just barely worked... --- .../D. Closest Equals.cpp | 261 ++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 VK Cup 2015 - Qualification Round 1/D. Closest Equals.cpp diff --git a/VK Cup 2015 - Qualification Round 1/D. Closest Equals.cpp b/VK Cup 2015 - Qualification Round 1/D. Closest Equals.cpp new file mode 100644 index 0000000..f162007 --- /dev/null +++ b/VK Cup 2015 - Qualification Round 1/D. Closest Equals.cpp @@ -0,0 +1,261 @@ +#include + +using namespace std; + +#define V vector + +#define rmin(a, b) a = min(a, b) +#define rmax(a, b) a = max(a, b) + +#define rep(i, lim) for (size_t i = 0; i < (lim); i++) +#define nrep(i, s, lim) for (size_t i = s; i < (lim); i++) + +#define repv(i, v) for (auto &i : (v)) +#define fillv(v) for (auto &itr_ : (v)) { cin >> itr_; } +#define sortv(v) sort(v.begin(), v.end()) +#define all(v) (v).begin(), (v).end() + +using vi = vector; +using vvi = vector; +using vvvi = vector; +using vvvvi = vector; + +using ll = long long; + +using vl = vector; +using vvl = vector; +using vvvl = vector; +using vvvvl = vector; + +template +auto operator<<(ostream &os, const vector &vec)->ostream& { + os << vec[0]; + for (size_t i = 1; i < vec.size(); i++) { + os << ' ' << vec[i]; + } + os << '\n'; + return os; +} + +template +auto operator>>(istream &is, vector &vec)->istream& { + for (auto &i : vec) { + is >> i; + } + return is; +} + +template +auto operator<<(ostream &os, const vector> &vec)->ostream& { + for (auto &i : vec) { + os << i[0]; + for (size_t j = 1; j < i.size(); j++) { + os << ' ' << i[j]; + } + os << '\n'; + } + return os; +} + +template +auto operator>>(istream &is, vector> &vec)->istream& { + for (auto &i : vec) { + for (auto &j : i) { + is >> j; + } + } + return is; +} + +const int inf = INT32_MAX >> 1; + +int closepower2(int n) +{ + return n == 1 ? 1 : 1 << (sizeof(n) * 8 - __builtin_clz(n - 1)); +} + +int nextpower2(int n) +{ + return n == 1 ? 1 : sizeof(n) * 8 - __builtin_clz(n - 1); +} + +class segtree_min { + struct segnode { + int content; + int left, right; + + segnode(): content(inf), left(0), right(0) {} + segnode(int content): content(content), left(0), right(0) {} + segnode(int content, int left, int right): + content(content), left(left), right(right) {} + + int getcontent() const { + return content == inf ? -1 : content; + } + }; + + vector nodes; + vector roots; + size_t alloc; + int n; + + int create_leaf(long long v) { + new (&nodes[alloc]) segnode(v); + alloc++; + return alloc - 1; + } + + int update_node(int l, int r) { + new (&nodes[alloc]) segnode(min(nodes[l].content, nodes[r].content), l, r); + alloc++; + return alloc - 1; + } + + int _update(int i, int l, int r, int f, long long v) { + if (l > f || r < f) { + return i; + } + + if (l == f && r == f) { + int now = create_leaf(v); + return now; + } + + int mid = (l + r) / 2; + int left = _update(nodes[i].left, l, mid, f, v); + int right = _update(nodes[i].right, mid + 1, r, f, v); + + if (nodes[i].left == left && nodes[i].right == right) { + return i; + } + + if (nodes[i].left != left) { + return update_node(left, nodes[i].right); + } + return update_node(nodes[i].left, right); + } + + long long search(int i, int l, int r, int ql, int qr) { + if (l > qr || r < ql) { + return inf; + } + + if (l >= ql && r <= qr) { + return nodes[i].content; + } + + int m = (l + r) / 2; + return min(search(nodes[i].left, l, m, ql, qr), search(nodes[i].right, m + 1, r, ql, qr)); + } + + public: + segtree_min() = delete; + + segtree_min(size_t n): nodes(closepower2(n) * 2 + nextpower2(n) * closepower2(n) + closepower2(n)), + roots({0}), alloc(closepower2(n) * 2 - 1), n(closepower2(n) - 1) { + for (size_t i = 0; i < closepower2(n) - 1; i++) { + new (&nodes[i]) segnode(inf, i * 2 + 1, i * 2 + 2); + } + } + + void update(int i, long long v) { + int root = _update(roots.back(), 0, n, i, v); + roots.push_back(root); + } + + long long query(int l, int r) { + int root = roots[r]; + // int root = roots.back(); + l--, r--; + return search(root, 0, n, l, r); + } + + void print() { + int root = roots.back(); + queue q; + q.push(root); + while (!q.empty()) { + int p = q.front(); + q.pop(); + if (nodes[p].left != 0) { + q.push(nodes[p].left); + q.push(nodes[p].right); + } + cout << nodes[p].getcontent() << ' '; + } + cout << '\n'; + } + + void print_full() { + int root = roots.back(); + queue q; + q.push(root); + while (!q.empty()) { + int p = q.front(); + q.pop(); + if (nodes[p].left != 0) { + q.push(nodes[p].left); + q.push(nodes[p].right); + } + cout << p << ": " << nodes[p].getcontent() << ' ' << nodes[p].left << ' ' << nodes[p].right << '\n'; + } + } + + void print_roots() { + for (auto i : roots) { + cout << i << ' '; + } + cout << '\n'; + } + + void print_all_ver() { + for (auto i : roots) { + queue q; + q.push(i); + while (!q.empty()) { + int p = q.front(); + q.pop(); + if (nodes[p].left != 0) { + q.push(nodes[p].left); + q.push(nodes[p].right); + } + cout << nodes[p].getcontent() << ' '; + } + cout << '\n'; + } + } +}; + +int main() +{ + ios::sync_with_stdio(false); + cin.tie(nullptr); + + int n, m; + cin >> n >> m; + vector nums(n); + for (auto &i : nums) { + cin >> i; + } + + segtree_min seg(n); + map dis; + + for (size_t i = 0; i < n; i++) { + long long now = inf; + if (dis.find(nums[i]) != dis.end()) { + now = i - dis[nums[i]]; + seg.update(dis[nums[i]], now); + } else { + seg.update(i, inf); + } + dis[nums[i]] = i; + } + + while (m--) { + int l, r; + cin >> l >> r; + long long ans = seg.query(l, r); + cout << (ans == inf ? -1 : ans) << '\n'; + } +}