Cod sursa(job #1143062)

Utilizator manutrutaEmanuel Truta manutruta Data 14 martie 2014 17:33:13
Problema Hotel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.56 kb
#include <iostream>
#include <fstream>

using namespace std;
struct AINT {
    int mark, key, stkey, drkey;

    AINT() {
        mark = 0; key = 0; stkey = 0; drkey = 0;
    }
    void reset() {
        mark = 0; key = 0; stkey = 0; drkey = 0;
    }
};

#define MAXN 100005
#define MAXAINT (1 << 18)

ifstream f("hotel.in");
ofstream g("hotel.out");

int n;
int a[MAXN];
AINT aint[MAXAINT];

void attrib(int nod, int mark, int val = 0)
{
    switch (mark) {
        case 0: aint[nod].mark = 0; aint[nod].stkey = aint[nod].key = aint[nod].drkey = val; break;
        case 1: aint[nod].mark = 1; aint[nod].stkey = aint[nod].key = aint[nod].drkey = 0; break;
        case -1:
            attrib(nod, 1);
            aint[nod].mark = -1;
            aint[nod].key = max(aint[nod << 1].key, aint[(nod << 1) + 1].key);
            aint[nod].key = max(aint[nod].key, aint[nod << 1].drkey + aint[(nod << 1) + 1].stkey);
            if (aint[nod << 1].mark == 0) {
                aint[nod].stkey = aint[nod << 1].key + aint[(nod << 1) + 1].stkey;
                aint[nod].key = max(aint[nod].key, aint[nod].stkey);
                aint[nod].drkey = aint[(nod << 1) + 1].drkey;
            } else
            if (aint[(nod << 1) + 1].mark == 0) {
                aint[nod].drkey = aint[(nod << 1) + 1].key + aint[nod << 1].drkey;
                aint[nod].key = max(aint[nod].key, aint[nod].drkey);
                aint[nod].stkey = aint[nod << 1].stkey;
            } else  {
                aint[nod].stkey = aint[nod << 1].stkey;
                aint[nod].drkey = aint[(nod << 1) + 1].drkey;
            }
            break;
    }
}

void compileFirst(int st = 1, int dr = n, int nod = 1)
{
    attrib(nod, 0, dr - st + 1);
    if (st == dr) {
        return ;
    }

    int mij = ((st + dr) >> 1);
    compileFirst(st, mij, nod << 1);
    compileFirst(mij + 1, dr, (nod << 1) + 1);
}

void update(int mark, int x, int y, int st = 1, int dr = n, int nod = 1)
{
    //cout << nod << ' ' << aint[nod].mark << ": " << st << ' ' << dr << endl;
    if (x <= st && dr <= y) {
        attrib(nod, mark, dr - st + 1);
        //cout << nod << ' ' << aint[nod].mark << ": " << st << ' ' << dr << " -> " << aint[nod].stkey << ' ' << aint[nod].key << ' ' << aint[nod].drkey << endl;
        return ;
    }

    int mij = ((st + dr) >> 1);
    if (aint[nod].mark != -1) {
        attrib(nod << 1, aint[nod].mark, mij - st + 1);
        attrib((nod << 1) + 1, aint[nod].mark, dr - mij);
    }

    if (x <= mij) {
        update(mark, x, y, st, mij, nod << 1);
    }
    if (y > mij) {
        update(mark, x, y, mij + 1, dr, (nod << 1) + 1);
    }

    if (aint[nod << 1].mark == aint[(nod << 1) + 1].mark) {
        attrib(nod, aint[nod << 1].mark, dr - st + 1);
    } else {
        attrib(nod, -1);
    }

    //cout << nod << ' ' << aint[nod].mark <<  ": " << st << ' ' << dr << " -> " << aint[nod].stkey << ' ' << aint[nod].key << ' ' << aint[nod].drkey << endl;
}

int main()
{
    int p;
    f >> n >> p;
    compileFirst();

    for (int i = 1; i <= p; i++) {
        int op, x, y;
        f >> op;

        switch (op) {
            case 1: f >> x >> y; /*cout << endl << endl << "update: " << 1 << ' ' << x << ' ' << x + y - 1 << endl;*/ update(1, x, x + y - 1); break;
            case 2: f >> x >> y; /*cout << endl << endl << "update: " << 0 << ' ' << x << ' ' << x + y - 1 << endl;*/ update(0, x, x + y - 1); break;
            case 3: g << aint[1].key << '\n'; break;
        }
    }

    f.close();
    g.close();
    return 0;
}