Cod sursa(job #3131358)

Utilizator marius004scarlat marius marius004 Data 19 mai 2023 22:15:37
Problema Hotel Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.38 kb
#include <fstream>
#include <vector>

using namespace std;

ifstream fin("hotel.in");
ofstream fout("hotel.out");

enum LazyPropagationStatus {
    INSERT,
    DELETE,
    NOTHING
};

struct SegTreeNode {
    int prefix;
    int suffix;
    int answer;
    int length;
    LazyPropagationStatus status;

    SegTreeNode()
        : prefix(0), suffix(0), answer(0), length(0), status(LazyPropagationStatus::NOTHING) {}

    SegTreeNode(int prefix, int suffix, int answer, int length, LazyPropagationStatus status)
        : prefix(prefix), suffix(suffix), answer(answer), length(length), status(status) {}

    SegTreeNode(const SegTreeNode& left, const SegTreeNode& right) {
        this->length = left.length + right.length;
        this->prefix = (left.prefix == left.length) ? left.prefix + right.suffix : left.prefix;
        this->suffix = (right.suffix == right.length) ? right.suffix + left.suffix : right.suffix;
        this->answer = max(max(left.answer, right.answer), left.suffix + right.prefix);
        this->status = LazyPropagationStatus::NOTHING;
    }

    friend ostream &operator<<(ostream &os, const SegTreeNode &node) {
        os << node.answer;
        return os;
    }
};

vector<SegTreeNode> segTree;

void build(int node, int left, int right) {
    if (left == right) {
        segTree[node] = SegTreeNode(1, 1, 1, 1, LazyPropagationStatus::NOTHING);
        return;
    }

    int mid = (left + right) / 2;
    build(2 * node, left, mid);
    build(2 * node + 1, mid + 1, right);

    segTree[node] = SegTreeNode(segTree[2 * node], segTree[2 * node + 1]);
}

void lazyUpdate(int node, int left, int right) {
    if (segTree[node].status == LazyPropagationStatus::DELETE) {
        segTree[node].prefix = segTree[node].suffix = segTree[node].answer = 0;
        segTree[2 * node].status = segTree[2 * node + 1].status = LazyPropagationStatus::DELETE;
    } else if (segTree[node].status == LazyPropagationStatus::INSERT) {
        segTree[node].prefix = segTree[node].suffix = right - left + 1;
        segTree[2 * node].status = segTree[2 * node + 1].status = LazyPropagationStatus::INSERT;
    }

    segTree[node].status = LazyPropagationStatus::NOTHING;
}

void propagateToChildren(int node, int left, int right) {
    int mid = (left + right) / 2;
    lazyUpdate(2 * node, left, mid);
    lazyUpdate(2 * node + 1, mid + 1, right);
}

void update(int node, int left, int right, int a, int b, LazyPropagationStatus status) {
    lazyUpdate(node, left, right);

    if (left > b || right < a)
        return;

    if (left >= a && right <= b) {
        segTree[node].status = status;
        return;
    }

    int mid = (left + right) / 2;
    update(2 * node, left, mid, a, b, status);
    update(2 * node + 1, mid + 1, right, a, b, status);
    propagateToChildren(node, left, right);

    segTree[node] = SegTreeNode(segTree[2 * node], segTree[2 * node + 1]);
}

int main() {
    int n, p;
    fin >> n >> p;

    segTree.resize(4 * n + 1);
    build(1, 1, n);

    while (p--) {
        int q;
        fin >> q;

        if (q == 1) {
            int i, m;
            fin >> i >> m;
            update(1, 1, n, i, i + m - 1, LazyPropagationStatus::DELETE);
        } else if (q == 2) {
            int i, m;
            fin >> i >> m;
            update(1, 1, n, i, i + m - 1, LazyPropagationStatus::INSERT);
        } else {
            lazyUpdate(1, 1, n);
            fout << segTree[1] << '\n';
        }
    }

    return 0;
}