Cod sursa(job #2817237)

Utilizator Asgari_ArminArmin Asgari Asgari_Armin Data 13 decembrie 2021 12:09:48
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.87 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 1e5;

struct Node {
  int ans, maxpref, maxsuf;
  bool full, emptys;
  int lazy;

  void initempty(int node, int from, int to) {
    maxpref = maxsuf = ans = to - from + 1;
    full = 0;
    emptys = 1;
  }

  void initfull(int node, int from, int to) {
    ans = maxpref = maxsuf = 0;
    full = 1;
    emptys = 0;
  }

  void constructor() {
    ans = maxpref = maxsuf = full = emptys = lazy = 0;
  }

};

Node aint[4 * NMAX + 2];

void cleannode(int node, int from, int to) {
  if (aint[node].lazy > 0) {
    if (aint[node].lazy == 1)
      aint[node].initfull(node, from, to);
    else
      aint[node].initempty(node, from, to);

    if (from != to)
      aint[2 * node].lazy = aint[2 * node + 1].lazy = aint[node].lazy;

    aint[node].lazy = 0;
  }
}

Node join(Node a, Node b) {
  Node x;
  x.constructor();

  if (b.emptys)
    x.maxsuf = b.maxsuf + a.maxsuf;
  else
    x.maxsuf = b.maxsuf;

  if (a.emptys)
    x.maxpref = a.maxpref + b.maxpref;
  else
    x.maxpref = a.maxpref;

  x.ans = max(max(a.ans, b.ans), a.maxsuf + b.maxpref);
  x.emptys = a.emptys & b.emptys;
  x.full = a.full & b.full;

  return x;
}

void build(int node, int from, int to) {
  if (from == to) {
    aint[node].initempty(node, from, to);
    return ;
  }

  int mid = (from + to) >> 1;

  build(2 * node, from, mid);
  build(2 * node + 1, mid + 1, to);

  aint[node] = join(aint[2 * node], aint[2 * node + 1]);
}

void updateLazy(int node, int from, int to, int x, int y, int tip) {
  if (from == x && to == y) {
    aint[node].lazy = tip + 1;
    cleannode(node, from, to);
    return ;
  }

  int mid = (from + to) >> 1;

  cleannode(2 * node, from, mid);
  cleannode(2 * node + 1, mid + 1, to);

  if (x <= mid)
    updateLazy(2 * node, from, mid, x, min(y, mid), tip);
  if (y > mid)
    updateLazy(2 * node + 1, mid + 1, to, max(x, mid + 1), y, tip);

  aint[node] = join(aint[2 * node], aint[2 * node + 1]);
}

Node query(int node, int from, int to, int x, int y) {
  cleannode(node, from, to);
  if (from == x && y == to)
    return aint[node];

  int mid = (from + to) >> 1;

  if (y <= mid)
    return query(2 * node, from, mid, x, y);
  else if (x > mid)
    return query(2 * node + 1, mid + 1, to, x, y);
  return join(query(2 * node, from, mid, x, mid),
              query(2 * node + 1, mid + 1, to, mid + 1, y));
}

int main() {
  int n, q, i, m, tip;

  fin >> n >> q;

  build(1, 1, n);
  while (q--){
    fin >> tip;

    if (tip == 1) {
      fin >> i >> m;
      updateLazy(1, 1, n, i, i + m - 1, 0);
    }
    else if (tip == 2) {
      fin >> i >> m;
      updateLazy(1, 1, n, i, i + m - 1, 1);
    }
    else
      fout << aint[1].ans << "\n";
  }
  return 0;
}