Cod sursa(job #1138868)

Utilizator manutrutaEmanuel Truta manutruta Data 10 martie 2014 18:00:43
Problema Hotel Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.42 kb
#include <iostream>
#include <fstream>

using namespace std;
struct ASQRT {
    int key, left, right, mx;
};

#define leftSon(i) ((i) * 2)
#define rightSon(i) ((i) * 2 + 1)

#define MAXN 100005

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

int n, m;
ASQRT asqrt[MAXN]; int size;
int a[MAXN];
int sp[MAXN];

void setint(int beg, int en, int op)
{
    if (op == 2) {
        return ;
    }
    for (int i = beg; i <= en; i++) {
        a[i] = op;
    }
}

void update(int op, int setst, int setdr)
{
    for (int i = 1; i <= size + 1; i++) {
        if (setst <= (i - 1) * size + 1 && i * size <= setdr) {
            asqrt[i].key = op;
        }
    }

    for (int i = 1; i <= size + 1; i++) {
        if (asqrt[i].key == op) {
            continue;
        }

        bool work = false;
        if ((i - 1) * size + 1 <= setst && setdr <= i * size) {
            setint((i - 1) * size + 1, i * size, asqrt[i].key);
            for (int j = setst; j <= setdr; j++) {
                a[j] = op;
            }
            work = true;
        } else if ((i - 1) * size + 1 <= setst && setst <= i * size) {
            setint((i - 1) * size + 1, i * size, asqrt[i].key);
            for (int j = i * size; j >= setst; j--) {
                a[j] = op;
            }
            work = true;
        } else if ((i - 1) * size + 1 <= setdr && setdr <= i * size) {
            setint((i - 1) * size + 1, i * size, asqrt[i].key);
            for (int j = (i - 1) * size + 1; j <= setdr; j++) {
                a[j] = op;
            }
            work = true;
        }

        if (work == true) {
            int f1 = 0, f0 = 0;
            for (int j = (i - 1) * size + 1; j <= i * size; j++) {
                if (a[j] == 0) {
                    f0 = 1;
                }
                if (a[j] == 1) {
                    f1 = 1;
                }
                if (f0 == 1 && f1 == 1) {
                    break;
                }
            }
            if (f0 == 1 && f1 == 0) {
                asqrt[i].key = 0;
            } else if (f0 == 0 && f1 == 1) {
                asqrt[i].key = 1;
            } else {
                asqrt[i].key = 2;
            }
        }
    }
}

int query()
{
    int mx = 0, cur = 0;
    for (int i = 1; i <= size + 1; i++) {
        if (asqrt[i].key == 1) {
            cur = 0;
            continue;
        }
        if (i * size > n && asqrt[i].key == 0) {
            cur += n - (i - 1) * size;
            mx = max(mx, cur);
            continue;
        }

        if (asqrt[i].key == 0) {
            cur += size;
            mx = max(mx, cur);
        } else {
            for (int j = (i - 1) * size + 1; j <= i * size; j++) {
                if (a[j] == 0) {
                    cur++;
                    mx = max(mx, cur);
                } else {
                    cur = 0;
                }
            }
        }
    }
    return mx;
}

int main()
{
    f >> n >> m;

    while (size * size <= n) size++;
    size--;

    for (int i = 1; i <= m; i++) {
        int op, x, y;
        f >> op;
        if (op < 3) {
            f >> x >> y;
        }

        switch (op) {
            case 1: update(1, x, x + y - 1); break;
            case 2: update(0, x, x + y - 1); break;
            case 3: g << query() << '\n'; break;
        }
    }

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