Cod sursa(job #1823557)

Utilizator mirupetPetcan Miruna mirupet Data 6 decembrie 2016 16:44:21
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.55 kb
#include <assert.h>
#include <stdio.h>
#include <algorithm>


using std::max;


struct Node {
  int size;
  int max;
  Node* left;
  Node* right;
};


Node* emptyNode = new Node();


void recompute(Node* root) {
  root->max = max(root->left->max, root->right->max);
}


// begin inclusv
// end exclusiv
Node* build(int* begin, int* end) {
  Node* root = new Node();
  root->size = end - begin;
  if (root->size == 1) {
    root->left = emptyNode;
    root->right = emptyNode;
    root->max = *begin;
  } else {
    root->left = build(begin, begin + root->size / 2);
    root->right = build(begin + root->size / 2, end);
    recompute(root);
  }
  return root;
}


void update(Node* root, int index, int value) {
  assert(0 <= index && index < root->size);
  if (root->size == 1) {
    root->max = value;
  } else {
    if (index < root->left->size) {
      update(root->left, index, value);
    } else { // if (root->left->size <= index)
      update(root->right, index - root->left->size, value);
    }
    recompute(root);
  }
}


// left inclus
// right exclus
int query(Node* root, int left, int right) {
  assert(0 <= left && left < right && right <= root->size);
  if (root->size == right - left) {
    return root->max;
  } else if (right <= root->left->size) {
    return query(root->left, left, right);
  } else if (root->left->size <= left) {
    return query(root->right, left - root->left->size, right - root->left->size);
  } else {
    return max(query(root->left, left, root->left->size),
               query(root->right, 0, right - root->left->size));
  }
}
/*
q(2, 8)
            11
   [---------------------]
   0 1 2 3 4  5 6 7 8 9 10
        5         6
   [--------][-----------]
   0 1 2 3 4  0 1 2 3 4  5
//*/


void print(Node* root, int depth = 0) {
  if (root != emptyNode) {
    for(int i = 0; i < depth; i++)
      printf("  ");
    printf("%d %d\n", root->size, root->max);
    print(root->left, depth + 1);
    print(root->right, depth + 1);
  }
  if (depth == 0)
    printf("\n");
}


int main() {
  freopen("arbint.in", "r", stdin);
  freopen("arbint.out", "w", stdout);
  int N, M;
  scanf("%d%d", &N, &M);
  int* A = new int[N];
  for(int i = 0; i < N; i++)
    scanf("%d", &A[i]);
  Node* root = build(A, A + N);
  //print(root);
  for(int i = 0; i < M; i++) {
	int t, a, b;
    scanf("%d%d%d", &t, &a, &b);
    if (t == 0) {
      printf("%d\n", query(root, a - 1, b));
    } else {
      update(root, a - 1, b);
      //print(root);
    }
  }
  return 0;
}