Cod sursa(job #2545022)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 12 februarie 2020 19:30:34
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.59 kb
#include <fstream>

using namespace std;

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

const int NMAX = 100000;

///AINT///

struct Node
{
    int dimension;
    int maxLen, maxPref, maxSuf;
};

Node Merge(Node A, Node B)
{
    Node res;

    res.dimension = A.dimension + B.dimension;
    res.maxLen = max(A.maxLen, max(B.maxLen, A.maxSuf + B.maxPref));

    if(A.maxLen == A.dimension && B.maxLen == B.dimension)
    {
        res.maxPref = res.dimension;
        res.maxSuf = res.dimension;
    }
    else if(A.maxLen == A.dimension)
    {
        res.maxPref = A.dimension + B.maxPref;
        res.maxSuf = B.maxSuf;
    }
    else if(B.maxLen == B.dimension)
    {
        res.maxPref = A.maxPref;
        res.maxSuf = A.maxSuf + B.dimension;
    }
    else
    {
        res.maxPref = A.maxPref;
        res.maxSuf = B.maxSuf;
    }

    return res;
}

struct Aint
{
    Node v[4 * NMAX];
    int lazy[4 * NMAX];

    void Build(int node, int st, int dr)
    {
        if(st == dr)
        {
            v[node].dimension = 1;
            v[node].maxLen = 1;
            v[node].maxPref = 1;
            v[node].maxSuf = 1;

            return ;
        }

        int mid = (st + dr) / 2;

        Build(2 * node, st, mid);
        Build(2 * node + 1, mid + 1, dr);

        v[node] = Merge(v[2 * node], v[2 * node + 1]);
    }

    void UpdateAdd(int node, int st, int dr, int l, int r)
    {
        if(lazy[node] != 0)
        {
            if(lazy[node] == -1)
            {
                v[node].maxLen = 0;
                v[node].maxPref = 0;
                v[node].maxSuf = 0;

                if(st != dr)
                    lazy[2 * node] = -1, lazy[2 * node + 1] = -1;
            }
            else
            {
                v[node].maxLen = v[node].dimension;
                v[node].maxPref = v[node].dimension;
                v[node].maxSuf = v[node].dimension;

                if(st != dr)
                    lazy[2 * node] = 1, lazy[2 * node + 1] = 1;
            }

            lazy[node] = 0;
        }

        if(r < st || l > dr)
            return;

        if(l <= st && dr <= r)
        {
            v[node].maxLen = 0;
            v[node].maxPref = 0;
            v[node].maxSuf = 0;

            if(st != dr)
                lazy[2 * node] = lazy[2 * node + 1] = -1;

            return ;
        }

        int mid = (st + dr) / 2;

        UpdateAdd(2 * node, st, mid, l, r);
        UpdateAdd(2 * node + 1, mid + 1, dr, l, r);

        v[node] = Merge(v[2 * node], v[2 * node + 1]);
    }

    void UpdateSubtract(int node, int st, int dr, int l, int r)
    {
        if(lazy[node] != 0)
        {
            if(lazy[node] == -1)
            {
                v[node].maxLen = 0;
                v[node].maxPref = 0;
                v[node].maxSuf = 0;

                if(st != dr)
                    lazy[2 * node] = -1, lazy[2 * node + 1] = -1;
            }
            else
            {
                v[node].maxLen = v[node].dimension;
                v[node].maxPref = v[node].dimension;
                v[node].maxSuf = v[node].dimension;

                if(st != dr)
                    lazy[2 * node] = 1, lazy[2 * node + 1] = 1;
            }

            lazy[node] = 0;
        }


        if(r < st || l > dr)
            return;

        if(l <= st && dr <= r)
        {
            v[node].maxLen = v[node].dimension;
            v[node].maxPref = v[node].dimension;
            v[node].maxSuf = v[node].dimension;

            if(st != dr)
                lazy[2 * node] = lazy[2 * node + 1] = 1;

            return ;
        }

        int mid = (st + dr) / 2;

        UpdateSubtract(2 * node, st, mid, l, r);
        UpdateSubtract(2 * node + 1, mid + 1, dr, l, r);

        v[node] = Merge(v[2 * node], v[2 * node + 1]);
    }

    int Query()
    {
        return v[1].maxLen;
    }
};

Aint aint;

///AINT///

int N, P;

int main()
{
    fin >> N >> P;

    aint.Build(1, 1, N);

    for(int i = 1; i <= P; i++)
    {
        int type;
        fin >> type;
        int pos, cant;

        if(type == 1)
        {
            fin >> pos >> cant;
            aint.UpdateAdd(1, 1, N, pos, pos + cant - 1);
        }
        else if(type == 2)
        {
            fin >> pos >> cant;

            if(pos == 9 && cant == 2)
                type++;

            aint.UpdateSubtract(1, 1, N, pos, pos + cant - 1);
        }
        else
            fout << aint.Query() << '\n';

    }

    return 0;
}