Cod sursa(job #1199504)

Utilizator RazvanR104Razvan-Andrei Ciocoiu RazvanR104 Data 19 iunie 2014 16:13:27
Problema Hotel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.68 kb
#include <iostream>
#include <iomanip>
#include <fstream>

#include <algorithm>
#include <bitset>
#include <deque>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#if __cplusplus > 199711L
#include <unordered_map>
#include <unordered_set>
#endif

#include <cstdio>
#include <ctime>
#include <cmath>
#include <cstring>
#include <cstdlib>

using namespace std;

typedef long long int64;

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

int N, P;
int middle[4 * 100010], lt[4 * 100010], rt[4 * 100010], free_max[4 * 100010], lazy[4 * 100010];

class SegmentTree {

public:
    SegmentTree() {}
    SegmentTree(const int N) {
        /*middle.reserve(4 * N);
        lt.reserve(4 * N);
        rt.reserve(4 * N);
        lazy.reserve(4 * N);
        free_max.reserve(4 * N);*/
        build(1, 1, N);
    }

    void update(const int node, const int left, const int right, const int qleft, const int qright, const int value) {
        if (lazy[node] == 1) { //clear
            middle[node] = lt[node] = rt[node] = free_max[node] = right - left + 1;
            if (left != right) lazy[node * 2] = lazy[node * 2 + 1] = 1;
            lazy[node] = 0;
        }
        else if (lazy[node] == 2) { //mark new guests
            middle[node] = lt[node] = rt[node] = free_max[node] = 0;
            if (left != right) lazy[node * 2] = lazy[node * 2 + 1] = 2;
            lazy[node] = 0;
        }

        if (left > right || qleft > right || qright < left) return;

        if (qleft <= left && qright >= right) {
            if (value == 1) {
                middle[node] = lt[node] = rt[node] = free_max[node] = right - left + 1;
                if (left != right) lazy[node * 2] = lazy[node * 2 + 1] = 1;
            }
            else if (value == 2) {
                middle[node] = lt[node] = rt[node] = free_max[node] = 0;
                if (left != right) lazy[node * 2] = lazy[node * 2 + 1] = 2;
            }
            return;
        }

        if (left == right) return;

        int div = (left + right) >> 1;
        update(node * 2, left, div, qleft, qright, value);
        update(node * 2 + 1, div + 1, right, qleft, qright, value);

        middle[node] = rt[node * 2] + lt[node * 2 + 1];
        lt[node] = lt[node * 2];
        if (lt[node * 2] == div - left + 1) lt[node] += lt[node * 2 + 1];
        rt[node] = rt[node * 2 + 1];
        if (rt[node * 2 + 1] == right - div) rt[node] += rt[node * 2];
        setmax(node);
    }

    int query() const {
        return free_max[1];
    }

private:
    //vector<int> middle, lt, rt, lazy, free_max;

    void build(const int node, const int left, const int right) {
        middle[node] = lt[node] = rt[node] = free_max[node] = right - left + 1;

        if (left == right) return;

        int div = (left + right) >> 1;
        build(node * 2, left, div);
        build(node * 2 + 1, div + 1, right);
    }

    void setmax(const int node) {
        free_max[node] = max(middle[node], max(lt[node], rt[node]));
        if (left != right) free_max[node] = max(free_max[node], max(free_max[node * 2], free_max[node * 2 + 1]));
    }
} Tree;

int main() {
    int op, i, m;
    fin >> N >> P;

    Tree = SegmentTree(N);

    while(P--) {
        fin >> op;
        if (op == 1) {
            fin >> i >> m;
            Tree.update(1, 1, N, i, i + m - 1, 2);
        }
        else if (op == 2) {
            fin >> i >> m;
            Tree.update(1, 1, N, i, i + m - 1, 1);
        }
        else fout << Tree.query() << '\n';
    }

    fin.close();
    fout.close();
    return 0;
}