Cod sursa(job #3200468)

Utilizator MihneaStoicaMihnea Teodor Stoica MihneaStoica Data 4 februarie 2024 19:41:39
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 6.09 kb
#include <bits/stdc++.h>

///Useful #defines

/*/ Put '*' between the slashes if not used
#define int int64_t
//*/
#define sz (size_t)
#define up (int64_t)
#define upp (uint64_t)
#define nln cout<<endl
#define fastio() {ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);}
#define forn(value, start, end, inc) for(auto value=start;value<=end;value+=inc)
#define rofn(value, start, end, inc) for(auto value=start;value>=end;value-=inc)
#define file_in(id, filename) ifstream id(filename)
#define file_out(id, filename) ofstream id(filename)
#define close(id) id.close()
#define constant(id_equal_val) constexpr auto id_equal_val
#ifdef LOCAL
#include "debug.h"
#else
#define debug(x...)
#define debug_single(x)
#define test(x)
#endif

using namespace std;

/// Required functions and classes

inline void setio(const string in, const string out);

/// Useful functions and classes

class _AIB
{
public:
    vector<int> v;
    vector<int> aib;
    _AIB (int newsize)
    {
        v.resize(newsize + 1);
        aib.resize(newsize + 1);
    }
    void update_set(int pos, int val)
    {
        int actual = val - v[pos];
        int i = pos;
        while (i < v.size())
        {
            aib[pos] += actual;
            i += (i & -i);
        }
    }
    void update_add(int pos, int val)
    {
        int actual = val;
        int i = pos;
        while (i < v.size())
        {
            aib[i] += actual;
            i += (i & -i);
        }
    }
    int req(int i)
    {
        int val = 0;
        while (i > 0)
        {
            val += aib[i];
            i -= (i & -i);
        }
        return val;
    }
    int query(int a, int b)
    {
        return req(b) - req(a - 1);
    }
};

/// Program settings
bool multiple_cases    = 0;  /// Multiple cases?

bool use_fastio        = 1;  /// Toggle fastio()
const string in        = "hotel.in"; /// File input
const string out       = "hotel.out"; /// File output

bool use_fastio_local  = 1;  /// Toggle fastio() (locally)
const string in_local  = ""; /// File input (locally)
const string out_local = ""; /// File output (locally)

void preinit()
{

}

struct SegTree
{
    int next_power_of_2(int n)
    {
        int p = 1;
        while(p <= n) p *= 2;
        return p;
    }

    int offset;
    vector<int> maxinterval, maxdr, maxst;
    vector<int> aint, lazy;

    SegTree(int n)
    {
        offset = next_power_of_2(n + 1);
        maxinterval.resize(2 * offset + 1);
        maxdr.resize(2 * offset + 1);
        maxst.resize(2 * offset + 1);
        aint.resize(2 * offset + 1);
        lazy.resize(2 * offset + 1);
        update(0, offset - 1, 1);
    }

    void push_lazy(int node, int l, int r)
    {
        if(node <= offset && lazy[node] != 0)
        {
            lazy[2 * node] = lazy[node];
            lazy[2 * node + 1] = lazy[node];
        }
        int length = (r - l + 1);
        if(lazy[node] == -1)
        {
            maxinterval[node] = length;
            maxdr[node] = length;
            maxst[node] = length;
        }
        else if(lazy[node] == 1)
        {
            maxinterval[node] = 0;
            maxdr[node] = 0;
            maxst[node] = 0;
        }
        lazy[node] = 0;
    }

    void _update(int node, int l, int r, int gl, int gr, int ch)
    {
        push_lazy(node, l, r);

        if(r < gl || gr < l) return;

        if(gl <= l && r <= gr)
        {
            lazy[node] = ch;
            push_lazy(node, l, r);
            return;
        }
        int mij = (l + r) / 2;
        _update(2 * node, l, mij, gl, gr, ch);
        _update(2 * node + 1, mij + 1, r, gl, gr, ch);

        maxinterval[node] = max(maxinterval[2 * node], maxinterval[2 * node + 1]);
        maxinterval[node] = max(maxinterval[node], maxdr[2 * node] + maxst[2 * node + 1]);

        maxdr[node] = maxdr[2 * node + 1];
        if(maxdr[node] == r - mij)
            maxdr[node] = maxdr[2 * node] + r - mij;

        maxst[node] = maxst[2 * node];
        if(maxst[node] == mij - l + 1)
            maxst[node] = maxst[2 * node + 1] + mij - l + 1;
    }

    void update(int l, int r, int ch)
    {
        _update(1, 0, offset - 1, l, r, ch);
    }
};


void solve()
{
    int n, p; cin >> n >> p;
    SegTree st = SegTree(n);
    st.update(0, n - 1, -1);
    for(int i = 0; i < p; i++)
    {
        int type; cin >> type;
        if(type == 1)
        {
            int l, nr; cin >> l >> nr;
            st.update(l - 1, l + nr - 2, 1);
        }
        else if(type == 2)
        {
            int l, nr; cin >> l >> nr;
            st.update(l - 1, l + nr - 2, -1);
        }
        else
        {
            int rasp = st.maxinterval[1];
            cout << rasp << "\n";
        }
    }
    //return 0;
}

/**



*/

///  Nothing to see here...           /\
///                                  /||\
///                                 / || \
///                                   ||
///                                   ||
///                                   ||
///



























































































/// Are you still here... ?













































































































inline void setio (const string in, const string out)
{
    if (!in.empty()) freopen(in.c_str(), "r", stdin);
    if (!out.empty()) freopen(out.c_str(), "w", stdout);
}

void apply_settings()
{
    // LOCAL check
#ifndef LOCAL
    setio (in, out);
    if (use_fastio) fastio();
#else
    setio (in_local, out_local);
    if (use_fastio_local) fastio();
#endif
}

int32_t main()
{
    apply_settings();
/// Multiple testcases check
    int t = 1;
    if (multiple_cases) cin >> t;

/// Code
    preinit();
    while (t --) solve();

    return 0;
}