제출 #393602

#제출 시각아이디문제언어결과실행 시간메모리
393602KoDNew Home (APIO18_new_home)C++17
33 / 100
3293 ms162552 KiB
#include <bits/stdc++.h>

template <class T>
using Vec = std::vector<T>;

using ll = long long;

constexpr ll INF = 1000000000;
constexpr ll MAX = 200000000;

struct Event {
    Vec<int> query;
    Vec<int> remove;
    Event(): query(), remove() { }
};

int main() {
    int N, K, Q;
    std::cin >> N >> K >> Q;
    Vec<ll> X(N), A(N), B(N);
    Vec<int> T(N);
    for (int i = 0; i < N; ++i) {
        std::cin >> X[i] >> T[i] >> A[i] >> B[i];
        assert(A[i] == 1);
        X[i] *= 2;
        T[i] -= 1;
    }
    Vec<ll> L(Q), Y(Q);
    for (int i = 0; i < Q; ++i) {
        std::cin >> L[i] >> Y[i];
        L[i] *= 2;
    }
    Vec<std::multiset<ll>> store(K);
    std::map<ll, ll> map;
    for (int i = 0; i < N; ++i) {
        store[T[i]].insert(X[i]);
    }
    const auto add = [&](const ll x, const ll y) {
        while (!map.empty() and map.begin() -> first <= x) {
            auto itr = std::prev(map.upper_bound(x));
            if (itr -> second - (x - itr -> first) >= y) {
                return;
            }
            if (y - (x - itr -> first) >= itr -> second) {
                map.erase(itr);
            }
            else {
                break;
            }
        }
        while (!map.empty() and map.rbegin() -> first >= x) {
            auto itr = map.lower_bound(x);
            if (itr -> second - (itr -> first - x) >= y) {
                return;
            }
            if (y - (itr -> first - x) >= itr -> second) {
                map.erase(itr);
            }
            else {
                break;
            }
        }
        map.emplace(x, y);
    };
    const auto get = [&](const ll x) {
        ll ret = 0;
        {
            auto itr = std::prev(map.upper_bound(x));
            ret = std::max(ret, itr -> second - (x - itr -> first));
        }
        {
            auto itr = map.lower_bound(x);
            ret = std::max(ret, itr -> second - (itr -> first - x));
        }
        return ret;
    };
    for (int i = 0; i < K; ++i) {
        store[i].insert(-INF);
        store[i].insert(INF);
        auto itr = store[i].begin();
        while (std::next(itr) != store[i].end()) {
            const auto mid = (*std::next(itr) + *itr) / 2;
            const auto len = (*std::next(itr) - *itr) / 2;
            add(mid, len);
            ++itr;
        }
    } 
    Vec<ll> ans(Q);
    std::map<ll, Event> events;
    for (int i = 0; i < N; ++i) {
        events[B[i]].remove.push_back(i);
    }   
    for (int i = 0; i < Q; ++i) {
        events[Y[i]].query.push_back(i);
    }
    for (const auto& [time, event]: events) {
        for (const auto i: event.query) {
            ans[i] = get(L[i]);
        }
        for (const auto i: event.remove) {
            const auto t = T[i];
            const auto x = X[i];
            auto itr = store[t].find(x);
            assert(itr != store[t].end());
            add((*std::next(itr) + *std::prev(itr)) / 2, (*std::next(itr) - *std::prev(itr)) / 2);
            store[t].erase(itr);
        }
    }
    for (const auto x: ans) {
        if (x >= MAX) {
            std::cout << -1 << '\n';
        }
        else {
            std::cout << x / 2 << '\n';
        }
    }
    return 0;
}
#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...