Cod sursa(job #2753705)

Utilizator andrei.gatejAndrei Gatej andrei.gatej Data 24 mai 2021 00:15:13
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.06 kb
#include <iostream>
#include <fstream>
#include <math.h>

using namespace std;

ifstream f("arbint.in");
ofstream g("arbint.out");

int N, M;

int* segmentTree;

int computeSegmentTreeSize (int elementsCount) {
  // If it's a power of 2
  if (elementsCount & elementsCount - 1 == 0) {
    return 2 * elementsCount - 1;
  }

  // Otherwise, we must find the smallest power of 2
  // greater than `elementsCount`
  int nextPowerOf2 = int(ceil(log2(elementsCount)));

  return 2 * int(pow(2, nextPowerOf2)) - 1;
}

void addItemToTree (
  int startIdx,
  int endIdx,
  int indexInTree,
  int pos,
  int item
) {
  // Reached a leaf node
  if (startIdx == endIdx) {
    segmentTree[indexInTree] = item;

    return;
  }

  int mid = (startIdx + endIdx) / 2;
  if (pos <= mid) {
    // Working on the left subtree
    addItemToTree(startIdx, mid, 2 * indexInTree + 1, pos, item);
  } else {
    // Working on the right subtree
    addItemToTree(mid + 1, endIdx, 2 * indexInTree + 2, pos, item);
  }

  segmentTree[indexInTree] = max(segmentTree[2 * indexInTree + 1], segmentTree[2 * indexInTree + 2]);
}

int findMax (int startIdx, int endIdx, int indexInTree, int queryStartIdx, int queryEndIdx) {
  // No overlap
  if (queryStartIdx > endIdx || queryEndIdx < startIdx) {
    return -1;
  }
  
  // Full overlap
  if (queryStartIdx <= startIdx && queryEndIdx >= endIdx) {
    return segmentTree[indexInTree];
  }

  // Partial overlap
  int mid = (startIdx + endIdx) / 2;
  return max(
    findMax(startIdx, mid, 2 * indexInTree + 1, queryStartIdx, queryEndIdx),
    findMax(mid + 1, endIdx, 2 * indexInTree + 2, queryStartIdx, queryEndIdx)
  );
}

int main () {
  f >> N >> M;

  segmentTree = new int[computeSegmentTreeSize(N)];

  int elem;
  for (int i = 0; i < N; i++) {
    f >> elem;

    addItemToTree(0, N - 1, 0, i, elem);
  }
  
  int task, a, b;
  for (int i = 0; i < M; i++) {
    f >> task >> a >> b;

    if (task == 0) {
      g << findMax(0, N - 1, 0, a - 1, b - 1) << '\n';
    } else {
      addItemToTree(0, N - 1, 0, a - 1, b);
    }
  }

  f.close();
  g.close();

  delete[] segmentTree;
}