Cod sursa(job #2295511)

Utilizator ContDeRacistAliniateEBlat ContDeRacist Data 3 decembrie 2018 18:28:54
Problema Hotel Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.05 kb
#include <fstream>

using namespace std;

ifstream cin("hotel.in");
ofstream cout("hotel.out");

struct Naint {
    int px0, sx0, lsl, lsr;

    Naint () {
        px0 = 0; sx0 = 0; lsl = 0; lsr = 0;
    }
};

void sum(Naint & x, Naint a,  Naint b) {
    if (a.px0 >= a.sx0)
        x.px0 = b.px0;
    else
        x.px0 = a.px0;
    if (b.px0 >= b.sx0)
        x.sx0 = a.sx0;
    else
        x.sx0 = b.sx0;
    x.lsl = a.lsl;
    x.lsr = a.lsr;
    if (x.lsr - x.lsl < b.lsr - b.lsl) {
        x.lsl = b.lsl;
        x.lsr = b.lsr;
    }
    if (x.lsr - x.lsl < b.px0 - a.sx0) {
        x.lsl = a.sx0;
        x.lsr = b.px0;
    }
}

const int N = (1<<18) + 7;

Naint aint[N];
bool lazy[N][2];
int sq, dq, n;

void init(Naint & x, int a, int b, int c, int d) {
    x.px0 = a;
    x.sx0 = b;
    x.lsl = c;
    x.lsr = d;
}

void propaga(int nod, int st, int dr) {
    bool c;
    if (lazy[nod][0]) {
        lazy[nod][0] = false;
        c = 0;
    }
    else if (lazy[nod][1]) {
        lazy[nod][1] = false;
        c = 1;
    }
    else
        return;
    int mij = ((st + dr)>>1);
    if ((nod<<1) < N) {
        lazy[nod<<1][c] = 1;
        lazy[nod<<1][!c] = 0;
        if (c)
            init(aint[nod<<1], st - 1, mij + 1, mij, st - 1);
        else
            init(aint[nod<<1], mij, st, st, mij);
    }

    if ((nod<<1) + 1 < N) {
        lazy[(nod<<1) + 1][!c] = 0;
        lazy[(nod<<1) + 1][c] = 1;
        if (c)
            init(aint[(nod<<1) + 1], mij, dr + 1, dr, mij);
        else
            init(aint[(nod<<1) + 1], dr, mij + 1, mij + 1, dr);
    }
}

void update0(int st = 1, int dr = n, int nod = 1) {
    if (sq <= st && dr <= dq) {
        lazy[nod][0] = 1;
        lazy[nod][1] = 0;
        init(aint[nod], dr, st, st, dr);
        return;
    }
    propaga(nod, st, dr);
    int mij((st + dr)>>1);
    if (sq <= mij)
        update0(st, mij, nod<<1);
    if (dq > mij)
        update0(mij + 1, dr, (nod<<1) + 1);
    sum(aint[nod], aint[nod<<1], aint[(nod<<1) + 1]);
}

void update1(int st = 1, int dr = n, int nod = 1) {
    if (sq <= st && dr <= dq) {
        lazy[nod][0] = 0;
        lazy[nod][1] = 1;
        init(aint[nod], st - 1, dr + 1, dr, st - 1);
        return;
    }
    propaga(nod, st, dr);
    int mij((st + dr)>>1);
    if (sq <= mij && (nod<<1) < N)
        update1(st, mij, nod<<1);
    if (dq > mij && (nod<<1) + 1 < N)
        update1(mij + 1, dr, (nod<<1) + 1);
    sum(aint[nod], aint[nod<<1], aint[(nod<<1) + 1]);
}

void dfs(int st = 1, int dr = n, int nod = 1) {
    int mij((st + dr)>>1);
    aint[nod].px0 = dr;
    aint[nod].sx0 = st;
    aint[nod].lsl = st;
    aint[nod].lsr = dr;
    if (mij < dr) {
        dfs(st, mij, nod<<1);
        dfs(mij + 1, dr, (nod<<1) + 1);
    }
}

int main()
{
    int q, c;
    cin >> n >> q;
    dfs();
    while (q--) {
        cin >> c;
        if (c == 3) {
            cout << aint[1].lsr - aint[1].lsl + 1 << '\n';
            continue;
        }
        cin >> sq >> dq;
        dq += sq;
        --dq;
        if (c == 2)
            update0();
        else if (c == 1)
            update1();
    }
    return 0;
}