Cod sursa(job #1559833)

Utilizator StarGold2Emanuel Nrx StarGold2 Data 31 decembrie 2015 16:56:33
Problema Hotel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.53 kb
#include <cstdio>

const int DIM = 131072;
const int INF = 0x3f3f3f3f;
using namespace std;

struct segtree {int value, scmax, lscmax, rscmax;} SegTree[DIM * 4];
int N, X, Y, K, M, Array[DIM]; segtree answer;

void build (int node, int left, int right) {

    if (left == right) {

        SegTree[node].scmax = SegTree[node].lscmax = SegTree[node].rscmax = 1;
    }
    else {

        int middle = left + (right - left) / 2;

        build (  node * 2  ,    left   , middle);
        build (node * 2 + 1, middle + 1,  right);

        SegTree[node].scmax = SegTree[node].lscmax = SegTree[node].rscmax = right - left + 1;
    }

    return;
}

void update (int node, int left, int right, int start, int finish, int value) {

    int middle = left + (right - left) / 2;

    if (SegTree[node].value != 0) {
        SegTree[node * 2].value = SegTree[node * 2 + 1].value = SegTree[node].value;

        if (SegTree[node].value == 1) {
            SegTree[  node * 2  ].scmax = SegTree[  node * 2  ].lscmax = SegTree[  node * 2  ].rscmax = middle - left + 1;
            SegTree[node * 2 + 1].scmax = SegTree[node * 2 + 1].lscmax = SegTree[node * 2 + 1].rscmax = right - middle;
        }
        else {
            SegTree[  node * 2  ].scmax = SegTree[  node * 2  ].lscmax = SegTree[  node * 2  ].rscmax = 0;
            SegTree[node * 2 + 1].scmax = SegTree[node * 2 + 1].lscmax = SegTree[node * 2 + 1].rscmax = 0;
        }

        SegTree[node].value = 0;
    }

    if (start <= left && right <= finish) {
        SegTree[node].value = value;

        if (SegTree[node].value == 1)
            SegTree[node].scmax = SegTree[node].lscmax = SegTree[node].rscmax = right - left + 1;
        else
            SegTree[node].scmax = SegTree[node].lscmax = SegTree[node].rscmax = 0;
    } else {

        if (start <= middle)
            update (  node * 2  ,    left   , middle, start, finish, value);

        if (middle < finish)
            update (node * 2 + 1, middle + 1,  right, start, finish, value);

        SegTree[node].scmax = SegTree[node * 2].rscmax + SegTree[node * 2 + 1].lscmax;

        if (SegTree[node].scmax < SegTree[  node * 2  ].scmax)
            SegTree[node].scmax = SegTree[  node * 2  ].scmax;

        if (SegTree[node].scmax < SegTree[node * 2 + 1].scmax)
            SegTree[node].scmax = SegTree[node * 2 + 1].scmax;

        if (SegTree[node * 2].lscmax == middle - left + 1)
            SegTree[node].lscmax = SegTree[node * 2].lscmax + SegTree[node * 2 + 1].lscmax;
        else
            SegTree[node].lscmax = SegTree[node * 2].lscmax;

        if (SegTree[node * 2 + 1].rscmax == right - middle)
            SegTree[node].rscmax = SegTree[node * 2 + 1].rscmax + SegTree[node * 2].rscmax;
        else
            SegTree[node].rscmax = SegTree[node * 2 + 1].rscmax;
    }

    return;
}

segtree query (int node, int left, int right, int start, int finish) {

    int middle = left + (right - left) / 2;
    segtree value1, value2, value3;

    if (SegTree[node].value != 0) {
        SegTree[node * 2].value = SegTree[node * 2 + 1].value = SegTree[node].value;

        if (SegTree[node].value == 1) {
            SegTree[  node * 2  ].scmax = SegTree[  node * 2  ].lscmax = SegTree[  node * 2  ].rscmax = middle - left + 1;
            SegTree[node * 2 + 1].scmax = SegTree[node * 2 + 1].lscmax = SegTree[node * 2 + 1].rscmax = right - middle;
        }
        else {
            SegTree[  node * 2  ].scmax = SegTree[  node * 2  ].lscmax = SegTree[  node * 2  ].rscmax = 0;
            SegTree[node * 2 + 1].scmax = SegTree[node * 2 + 1].lscmax = SegTree[node * 2 + 1].rscmax = 0;
        }

        SegTree[node].value = 0;
    }

    if (start <= left && right <= finish) {

        return SegTree[node];
    } else {

        if (start <= middle)
            value1 = query (  node * 2  ,    left   , middle, start, finish);

        if (middle < finish)
            value2 = query (node * 2 + 1, middle + 1,  right, start, finish);

        if (start <= middle && !(middle < finish))
            return value1;

        if (!(start <= middle) && middle < finish)
            return value2;

        value3.scmax = value1.rscmax + value2.lscmax;

        if (value3.scmax < value1.scmax)
            value3.scmax = value1.scmax;

        if (value3.scmax < value2.scmax)
            value3.scmax = value2.scmax;

        if (value1.lscmax == middle - left + 1)
            value3.lscmax = value1.lscmax + value2.lscmax;
        else
            value3.lscmax = value1.lscmax;

        if (value2.rscmax == right - middle)
            value3.rscmax = value2.rscmax + value1.rscmax;
        else
            value3.rscmax = value2.rscmax;

        return value3;
    }
}

int main () {

    freopen ("hotel.in" ,"r", stdin );
    freopen ("hotel.out","w", stdout);

    scanf ("%d %d", &N, &M);
    build (1, 0, N - 1);

    for (int i = 0; i < M; i ++) {
        scanf ("%d", &K);

        switch (K) {

            case 1: {
                scanf ("%d %d", &X, &Y); Y += X - 1;
                update (1, 0, N - 1, X - 1, Y - 1, -1);

                break;
            }

            case 2: {
                scanf ("%d %d", &X, &Y); Y += X - 1;
                update (1, 0, N - 1, X - 1, Y - 1, +1);

                break;
            }

            case 3: {
                answer = query (1, 0, N - 1, 0, N - 1);
                printf ("%d\n", answer.scmax);

                break;
            }
        }
    }

    return 0;
}