Cod sursa(job #2814440)

Utilizator StarGold2Emanuel Nrx StarGold2 Data 8 decembrie 2021 09:29:53
Problema Hotel Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.14 kb
#include <fstream>
#include <algorithm>
#include <iostream>

const int N = 100000;

struct tree_node 
{
  int scmax;      // cea mai lunga subsecventa de 0
  int pref_scmax; // cel mai lung prefix de 0
  int suff_scmax; // cel mai lung sufix de 0
  int length;     // lungimea subsecventei
  int lazy;       // lazy
};

tree_node segment_tree[N * 4 + 1];

void update_lazy(int node, int left, int right)
{
  if (segment_tree[node].lazy == 0) {
    segment_tree[node].scmax = right - left + 1;
    segment_tree[node].pref_scmax = right - left + 1;
    segment_tree[node].suff_scmax = right - left + 1;
    segment_tree[node].length = right - left + 1;

    if (left != right) {
      segment_tree[node * 2].lazy = 0;
      segment_tree[node * 2 + 1].lazy = 0;
    }

    segment_tree[node].lazy = 2;
  }

  if (segment_tree[node].lazy == 1) {
    segment_tree[node].scmax = 0;
    segment_tree[node].pref_scmax = 0;
    segment_tree[node].suff_scmax = 0;
    segment_tree[node].length = right - left + 1;

    if (left != right) {
      segment_tree[node * 2].lazy = 1;
      segment_tree[node * 2 + 1].lazy = 1;
    }

    segment_tree[node].lazy = 2;
  }
}

tree_node update_node(tree_node left_node, tree_node right_node)
{
  tree_node current_node;

  current_node.length =
      left_node.length + right_node.length;
    
  current_node.pref_scmax =
      left_node.pref_scmax == left_node.length 
                            ? left_node.length + right_node.pref_scmax
                            : left_node.pref_scmax;

  current_node.suff_scmax =
      right_node.suff_scmax == right_node.length 
                             ? right_node.length + left_node.suff_scmax
                             : right_node.suff_scmax;
 
  current_node.scmax = 
      std::max(left_node.suff_scmax + right_node.pref_scmax,
               std::max(left_node.scmax, 
                        right_node.scmax));

  return current_node;
}

void update(int node, int left, int right, int query_left, int query_right, int state)
{
  if (query_left <= left and right <= query_right) {
    segment_tree[node].lazy = state;
  } else {
    int middle = (left + right) / 2;
    update_lazy(node, left, right);

    if (query_left <= middle)
      update(node * 2, left, middle, query_left, query_right, state);
    if (middle + 1 <= query_right)
      update(node * 2 + 1, middle + 1, right, query_left, query_right, state);

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

    segment_tree[node] = update_node(segment_tree[node * 2], 
                                     segment_tree[node * 2 + 1]);
  }
}

int main(int argc, const char *argv[])
{
  std::ifstream in("hotel.in"); 
  std::ofstream out("hotel.out");
  
  int n, q; 
  in >> n >> q;

  segment_tree[1].lazy = 0;

  while (q--) {
    int type; 
    in >> type;
    std::cout << type << " ";

    if (type <= 2) {
      int left, length;
      in >> left >> length;

      int right = left + length - 1;

      if (type == 1)
        update(1, 1, n, left, right, 1);
      else
        update(1, 1, n, left, right, 0);
    } else {
      update_lazy(1, 1, n);
      out << segment_tree[1].scmax << "\n";
    }
  }
  return 0;
}