Submission #1244568

#TimeUsernameProblemLanguageResultExecution timeMemory
1244568Joshua_AnderssonComparing Plants (IOI20_plants)C++20
14 / 100
4096 ms27716 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll inf = 1e18; typedef vector<ll> vi; typedef vector<vi> vvi; typedef pair<ll, ll> p2; #define rep(i, high) for (ll i = 0; i < (high); i++) #define repp(i, lo, high) for (ll i = (lo); i < (high); i++) #define repe(i, container) for (auto& i : container) #define sz(x) ((ll)(x).size()) #define all(x) begin(x), end(x) struct Tree { vector<p2> tree; vi lazy; Tree(int n) : tree(n*4), lazy(n*4) {} p2 merge(p2 a, p2 b) { if (a.first <= b.first) return a; return b; } void push(int x) { tree[x * 2].first += lazy[x]; lazy[x * 2] += lazy[x]; tree[x * 2+1].first += lazy[x]; lazy[x * 2 + 1] += lazy[x]; lazy[x] = 0; } void set(int x, int l, int r, int i, ll v) { if (l == r) return void(tree[x] = p2(v, l)); push(x); int mid = (l + r) / 2; if (i <= mid) set(x * 2, l, mid, i, v); else set(x * 2 + 1, mid + 1, r, i, v); tree[x] = merge(tree[x * 2], tree[x * 2 + 1]); } p2 query(int x, int l, int r, int ql, int qr) { if (r<ql || l>qr) return p2(inf, 0); if (l >= ql && r <= qr) return tree[x]; push(x); int mid = (l + r) / 2; return merge(query(x * 2, l, mid, ql, qr), query(x * 2 + 1, mid + 1, r, ql, qr)); } void add(int x, int l, int r, int ql, int qr, ll amount) { if (r<ql || l>qr) return; if (l >= ql && r <= qr) { tree[x].first += amount; lazy[x] += amount; return; } push(x); int mid = (l + r) / 2; add(x * 2, l, mid, ql, qr, amount); add(x * 2 + 1, mid + 1, r, ql, qr, amount); tree[x] = merge(tree[x * 2], tree[x * 2 + 1]); } }; int n,k; vi ljump; vi rjump; vi real_heights; void init(int K, std::vector<int> r) { k = K; n = sz(r); real_heights.resize(n); rjump.resize(n, -1); ljump.resize(n, -1); auto norm = [&](int x) { if (x < 0) x %= n, x += n; if (x >= n) return x % n; return x; }; Tree tree(n); rep(i, n) tree.set(1, 0, n - 1, i, r[i]); auto find_zero = [&](int ql, int qr) { ql = norm(ql); qr = norm(qr); p2 q; if (ql <= qr) q = tree.query(1, 0, n - 1, ql, qr); else q = tree.merge(tree.query(1, 0, n - 1, 0, qr), tree.query(1, 0, n - 1, ql, n - 1)); if (q.first == 0) return q.second; return -1LL; }; auto decrease = [&](int ql, int qr) { ql = norm(ql); qr = norm(qr); if (ql <= qr) tree.add(1, 0, n - 1, ql, qr, -1); else tree.add(1, 0, n - 1, 0, qr, -1), tree.add(1, 0, n - 1, ql, n - 1, -1); }; ll ind = n - 1; rep(i, n) { ll j = find_zero(0, n-1); if (j == -1) break; vi st = { j }; while (sz(st)) { ll u = st.back(); ll v = find_zero(u - k + 1, u - 1); if (v == -1) { st.pop_back(); real_heights[u] = ind--; decrease(u - k + 1, u - 1); tree.set(1, 0, n - 1, u, inf); } else { st.push_back(v); } } } rep(i, n) { repp(j, i + 1, i + k) { if (real_heights[norm(j)] < real_heights[i]) { rjump[i] = norm(j); break; } } repp(j, 1, k) { if (real_heights[norm(i-j)]<real_heights[i]) { ljump[i] = norm(i - j); break; } } } return; } int dist(int a, int b) { return min(abs(a - b), min(abs(a + n - b), abs(b + n - a))); } map<p2, int> cache; int reachable(int a, int b) { p2 s = p2(a, b); if (cache.count(s)) return cache[s]; // first, try CW int x = a; while (dist(rjump[x],b)>=k && rjump[x]!=-1) { x = rjump[x]; } if (dist(x,b)<k && real_heights[x] > real_heights[b]) return true; x = a; while (dist(x, ljump[x])>=k && ljump[x]!=-1) { x = ljump[x]; } if (dist(x, b) < k && real_heights[x]>real_heights[b]) return true; return false; } int compare_plants(int x, int y) { if (reachable(x, y)) return 1; if (reachable(y, x)) return -1; return 0; } #if _LOCAL static int q; static std::vector<int> r; static std::vector<int> x; static std::vector<int> y; static std::vector<int> answer; int main() { int n,k; assert(scanf("%d%d%d", &n, &k, &q) == 3); r.resize(n); answer.resize(q); for (int i = 0; i < n; i++) { int value; assert(scanf("%d", &value) == 1); r[i] = value; } x.resize(q); y.resize(q); for (int i = 0; i < q; i++) { assert(scanf("%d%d", &x[i], &y[i]) == 2); } fclose(stdin); init(k, r); for (int i = 0; i < q; i++) { answer[i] = compare_plants(x[i], y[i]); } for (int i = 0; i < q; i++) { printf("%d\n", answer[i]); } fclose(stdout); return 0; } #endif
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...