Submission #1140542

#TimeUsernameProblemLanguageResultExecution timeMemory
1140542marinovSprinklers (CEOI24_sprinklers)C++20
20 / 100
2094 ms13384 KiB
// Author: Robert Jaworski
#include <bits/stdc++.h>

#pragma GCC diagnostic ignored "-Wsign-compare"
using namespace std;

struct SegTree {
    static const vector<int>* translation;

    int value{}, update_by{}, update_to{-1};
    int left, middle, right;
    bool minValue{};

    unique_ptr<SegTree> l, r;

    SegTree(int from, int to) : left(from), middle((from + to) / 2), right(to) {
        if (left != right) {
            l = make_unique<SegTree>(left, middle);
            r = make_unique<SegTree>(middle+1, right);
        }
    }

    int get(int id) {
        relax();
        if (left == right && left == id)
            return value;
        if (id <= middle)
            return l->get(id);
        return r->get(id);
    }

    void change(int from, int to, int delta) {
        if (from <= translation->at(left) && translation->at(right) <= to) {
            update_by += delta;
            minValue += delta;
            return;
        }
        relax();
        if (l && r) {
            if (from <= translation->at(middle)) {
                l->change(from, to, delta);
            }
            if (to >= translation->at(middle+1)) {
                r->change(from, to, delta);
            }
            minValue = min(l->minValue, r->minValue);
        }
    }

    void set(int from, int to, int val) {
        if (from <= translation->at(left) && translation->at(right) <= to) {
            update_to = val;
            update_by = 0;
            minValue = value;
            return;
        }
        relax();
        if (l && r) {
            if (from <= translation->at(middle)) {
                l->set(from, to, val);
            }
            if (to >= translation->at(middle+1)) {
                r->set(from, to, val);
            }
            minValue = min(l->minValue, r->minValue);
        }
    }

    void relax() {
        if (left == right) {
            if (update_to >= 0) value = update_to;
            value += update_by;
            minValue = value;
        }
        else {
            if (update_to >= 0) {
                l->set(translation->at(0), translation->back(), update_to);
                r->set(translation->at(0), translation->back(), update_to);
            }
            l->change(translation->at(0), translation->back(), update_by);
            r->change(translation->at(0), translation->back(), update_by);
            minValue = min(l->minValue, r->minValue);
        }
        update_to = -1;
        update_by = 0;
    }
};
const vector<int>* SegTree::translation = nullptr;

bool check(int K, const std::vector<int>& s, const std::vector<int>& f, SegTree* tree, const vector<int>& c) {
    for (int i = 0; i < s.size(); i++) {
        if (c[i]) {
            tree->change(s[i], s[i] + K, 1);
        }
        else {
            tree->change(s[i] - K, s[i], 1);
        }
    }
    bool covered = tree->minValue > 0;
    tree->set(f[0], f.back(), 0);
    return covered;
}

bool bruteforce(int N, int M, int K, const vector<int>& s, const vector<int>& f, std::vector<int>& conf) {
    SegTree::translation = &f;
    SegTree tree(0, M-1);

    conf.resize(N, 0);
    for (int i = 0; i != N;) {
        if (check(K, s, f, &tree, conf)) return true;

        for (i = 0; i < N; i++) {
            conf[i] ^= 1;
            if (conf[i]) break;
        }
    }

    return false;
}

int main() {
    int N, M;
    cin >> N >> M;

    vector<int> s(N, 0), f(M, 0), conf;
    for (auto&& x : s) {
        cin >> x;
    }
    for (auto&& x : f) {
        cin >> x;
    }

    if (N == 1) {
        if (s.back() <= f[0]) {
            cout << (f.back() - s.back()) << endl << "R" << endl;
        }
        else if (s[0] >= f.back()) {
            cout << (s[0] - f[0]) << endl << "L" << endl;
        }
        else {
            cout << -1 << endl;
        }
        return 0;
    }

    int maxK = 1;
    int K, l, r;
    if (bruteforce(N, M, 0, s, f, conf)) {
        K = 0;
        goto END;
    }

    while (!bruteforce(N, M, maxK, s, f, conf)) maxK <<= 1;

    l = maxK / 2;
    r = maxK;
    while (l+1 < r) {
        int m = (l+r) / 2;
        if (bruteforce(N, M, m, s, f, conf)) {
            r = m;
        }
        else {
            l = m;
        }
    }

    K = r;
    if (!bruteforce(N, M, K, s, f, conf)) {
        cout << "Very bad" << endl;
    }

END:
    cout << K << endl;
    for (auto&& x : conf) {
        cout << (x ? 'R' : 'L');
    }
    cout << endl;

    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...