Cod sursa(job #2815953)

Utilizator StarGold2Emanuel Nrx StarGold2 Data 10 decembrie 2021 18:04:28
Problema Hotel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.92 kb
#include <fstream>
#include <algorithm>
#include <iostream>

const int N = 100000;

struct tree_node {
  int max;
  int left_max;
  int right_max;
  int lazy;
};

tree_node segment_tree[N * 4 + 1];

void update_lazy(int node, int left, int right)
{
  if (segment_tree[node].lazy == 1) {
    segment_tree[node].max = 0;
    segment_tree[node].left_max = 0;
    segment_tree[node].right_max = 0;

    if (left != right) {
      int left_son = node * 2,
          right_son = node * 2 + 1;

      segment_tree[left_son].lazy = 1;
      segment_tree[right_son].lazy = 1;
    }

    segment_tree[node].lazy = 0;
  } else
  if (segment_tree[node].lazy == 2) {
    segment_tree[node].max = right - left + 1;
    segment_tree[node].left_max = right - left + 1;
    segment_tree[node].right_max = right - left + 1;

    if (left != right) {
      int left_son = node * 2,
          right_son = node * 2 + 1;

      segment_tree[left_son].lazy = 2;
      segment_tree[right_son].lazy = 2;
    }

    segment_tree[node].lazy = 0;
  }
}

void update_node(int node, int left, int right)
{
  int middle = (left + right) / 2,
      left_son = node * 2,
      right_son = node * 2 + 1;
  
  segment_tree[node].left_max = 
    (segment_tree[left_son].left_max == middle - left + 1) ?
        (middle - left + 1) + segment_tree[right_son].left_max :
        segment_tree[left_son].left_max;
  
  segment_tree[node].right_max =
    (segment_tree[right_son].right_max == right - middle) ? 
        (right - middle) + segment_tree[left_son].right_max :
        segment_tree[right_son].right_max;
  
  segment_tree[node].max = 
    std::max(segment_tree[left_son].right_max + segment_tree[right_son].left_max,
             std::max(segment_tree[left_son].max, 
                      segment_tree[right_son].max));
}

void update(int node, int left, int right,
            int update_left, int update_right, int value)
{
  if (update_left <= left and right <= update_right)
    segment_tree[node].lazy = value;
  else {
    int middle = (left + right) / 2,
        left_son = node * 2,
        right_son = node * 2 + 1;

    update_lazy(node, left, right);

    if (update_left <= middle)
      update(left_son, left, middle, 
             update_left, update_right, value);
    if (middle + 1 <= update_right)
      update(right_son, middle + 1, right, 
             update_left, update_right, value);
      
    update_lazy(left_son, left, middle);
    update_lazy(right_son, middle + 1, right);

    update_node(node, left, right);
  }   
}

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 = 2;
  while (q--) {
    int type;
    in >> type;

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

      int right = left + count - 1;
      update(1, 1, n, left, right, type);
    } else {
      update_lazy(1, 1, n);
      out << segment_tree[1].max << "\n";
    }
  }

  return 0;
}