Cod sursa(job #3207317)

Utilizator Alex18maiAlex Enache Alex18mai Data 25 februarie 2024 20:23:46
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.01 kb

// g++ meditatii.cpp -o main 
// ./main

#include <bits/stdc++.h>

using namespace std;

struct Node {
    long long max_len, pref_len, suf_len, lazy;
};

vector<Node> tree;

Node combine(const Node & left_child, const Node & right_child, 
             const int & left, const int & right, const int & mid){
    Node curr_node;
    curr_node.lazy = 0;

    if (left_child.max_len == mid - left + 1){
        curr_node.pref_len = (mid - left + 1) + right_child.pref_len;
    }
    else{
        curr_node.pref_len = left_child.pref_len;
    }

    if (right_child.max_len == right - (mid+1) + 1){
        curr_node.suf_len = (right - (mid+1) + 1) + left_child.suf_len;
    }
    else{
        curr_node.suf_len = right_child.suf_len;
    }

    curr_node.max_len = max(max(left_child.max_len, right_child.max_len),
                            left_child.suf_len + right_child.pref_len);

    return curr_node;
}

void propagate(const int & node, const int & left, const int & right){
    if (!tree[node].lazy) 
        return;

    if (left != right){
        tree[node * 2].lazy = tree[node].lazy;
        tree[node * 2 + 1].lazy = tree[node].lazy;
    }

    if (tree[node].lazy == 1){
        // camerele se ocupa
        tree[node].max_len = 0;
        tree[node].pref_len = 0;
        tree[node].suf_len = 0;
    }
    if (tree[node].lazy == -1){
        // camere se elibereaza
        tree[node].max_len = right - left + 1;
        tree[node].pref_len = right - left + 1;
        tree[node].suf_len = right - left + 1;
    }

    tree[node].lazy = 0;
}

void init(int node, int left, int right){
    if (left == right){
        // leaf
        tree[node].max_len = 1;
        tree[node].pref_len = 1;
        tree[node].suf_len = 1;
        tree[node].lazy = 0;
        return;
    }

    int mid = (left + right) / 2;

    // left subtree
    init(node * 2, left , mid);
    // right subtree
    init(node * 2 + 1, mid + 1, right);

    // combine
    tree[node] = combine(tree[node * 2], tree[node * 2 + 1], left, right, mid);
}

void update(int node, int left, int right, int a, int b, int val){
    propagate(node, left, right);
    if (a <= left && right <= b){
        tree[node].lazy = val;
        return;
    }

    int mid = (left + right) / 2;

    if (a <= mid){
        update(node * 2, left, mid, a, b, val);
    }
    if (mid + 1 <= b){
        update(node * 2 + 1, mid + 1, right, a, b, val);
    }

    // combine
    propagate(node * 2, left, mid);
    propagate(node * 2 + 1, mid + 1, right);
    tree[node] = combine(tree[node * 2], tree[node * 2 + 1], left, right, mid);

}

Node query(int node, int left, int right, int a, int b){
    propagate(node, left, right);
    if (a <= left && right <= b){
        return tree[node];
    }

    int mid = (left + right) / 2;

    vector<Node> children;
    if (a <= mid){
        children.push_back(query(node * 2, left, mid, a, b));
    }
    if (mid + 1 <= b){
        children.push_back(query(node * 2 + 1, mid + 1, right, a, b));
    }

    if (children.size() == 1){
        return children[0];
    }

    return combine(children[0], children[1], left, right, mid);
}

int main() {

    // freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
    freopen("hotel.in", "r", stdin); freopen("hotel.out", "w", stdout);

    int n, m;
    cin>>n>>m;

    // initializare
    tree.resize(4*n);
    init(1, 1, n);

    for (int i=1; i<=m; i++){
        int t;
        cin>>t;

        if (t == 1){
            // se ocupa -> lazy = 1
            int a, b;
            cin>>a>>b;
            update(1, 1, n, a, a+b-1, 1);
        }
        else if (t == 2){
            // se elibereaza -> lazy = -1
            int a, b;
            cin>>a>>b;
            update(1, 1, n, a, a+b-1, -1);
        }
        else if (t == 3){
            // query
            Node ans = query(1, 1, n, 1, n);
            cout<<ans.max_len<<'\n';
        }
    }

    return 0;
}