Submission #349203

#TimeUsernameProblemLanguageResultExecution timeMemory
349203dolphingarlicThe Potion of Great Power (CEOI20_potion)C++14
56 / 100
1708 ms262144 KiB
#include <bits/stdc++.h>
using namespace std;

const int INF = 1e9;

struct Node {
    int mn, mx, cnt;
    Node *l, *r;

    Node(int val, int c): mn(val), mx(val), cnt(c), l(nullptr), r(nullptr) {}
    Node(Node *ll, Node *rr) {
        l = ll, r = rr;
        mn = INF, mx = -INF;
        if (l && l->cnt) mn = min(mn, l->mn), mx = max(mx, l->mx), cnt = 1;
        if (r && r->cnt) mn = min(mn, r->mn), mx = max(mx, r->mx), cnt = 1;
    }
};

vector<int> comp;
int idx[100000];
map<int, Node*> persist_roots[100000];

Node* update(Node *node, int pos, int val, int l = 1, int r = comp.size()) {
    if (l == r) return (node->cnt + val ? new Node(l, node->cnt + val) : nullptr);
    if (!node) node = new Node(0, 0);
    int mid = (l + r) / 2;
    if (pos > mid) {
        if (!node->r) node->r = new Node(0, 0);
        Node *ur = update(node->r, pos, val, mid + 1, r);
        if (!ur && !node->l) return nullptr;
        return new Node(node->l, ur);
    }
    if (!node->l) node->l = new Node(0, 0);
    Node *ul = update(node->l, pos, val, l, mid);
    if (!ul && !node->l) return nullptr;
    return new Node(ul, node->r);
}

pair<int, int> query(Node *node, int pos, int l = 1, int r = comp.size()) {
    if (!node) return {-INF, INF};
    if (pos < node->mn) return {-INF, node->mn};
    if (pos >= node->mx) return {node->mx, INF};
    int mid = (l + r) / 2;
    pair<int, int> l_ans = query(node->l, pos, l, mid);
    pair<int, int> r_ans = query(node->r, pos, mid + 1, r);
    return {max(l_ans.first, r_ans.first), min(l_ans.second, r_ans.second)};
}

void init(int N, int D, int H[]) {
    for (int i = 0; i < N; i++) comp.push_back(H[i]);
    sort(comp.begin(), comp.end());
    comp.erase(unique(comp.begin(), comp.end()), comp.end());
    for (int i = 0; i < N; i++) {
        idx[i] = lower_bound(comp.begin(), comp.end(), H[i]) - comp.begin() + 1;
        persist_roots[i][0] = nullptr;
    }
}

set<int> trust[100000];

void curseChanges(int U, int A[], int B[]) {
    for (int i = 0; i < U; i++) {
        if (trust[A[i]].find(B[i]) == trust[A[i]].end()) {
            trust[A[i]].insert(B[i]);
            trust[B[i]].insert(A[i]);
            persist_roots[A[i]][i + 1] = update(persist_roots[A[i]].rbegin()->second, idx[B[i]], 1);
            persist_roots[B[i]][i + 1] = update(persist_roots[B[i]].rbegin()->second, idx[A[i]], 1);
        } else {
            trust[A[i]].erase(B[i]);
            trust[B[i]].erase(A[i]);
            persist_roots[A[i]][i + 1] = update(persist_roots[A[i]].rbegin()->second, idx[B[i]], -1);
            persist_roots[B[i]][i + 1] = update(persist_roots[B[i]].rbegin()->second, idx[A[i]], -1);
        }
    }
}

int question(int x, int y, int v) {
    Node *x_root = prev(persist_roots[x].upper_bound(v))->second;
    Node *y_root = prev(persist_roots[y].upper_bound(v))->second;
    int ans = INF;
    for (int i = query(x_root, -1).second; i != INF; i = query(x_root, i).second) {
        pair<int, int> y_closest = query(y_root, i);
        if (y_closest.first != -INF)
            ans = min(ans, comp[i - 1] - comp[y_closest.first - 1]);
        if (y_closest.second != INF)
            ans = min(ans, comp[y_closest.second - 1] - comp[i - 1]);
    }
    return ans;
}
#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...