#include <stdio.h>
#include <stdlib.h>
#define null NULL
typedef struct node
{
int max;
int left_number;
int right_number;
struct node *right;
struct node *left;
}Node;
int max(int a, int b)
{
if (a > b)
return a;
return b;
}
Node * new_node()
{
Node * nod = (Node *) calloc(1, sizeof(Node));
return nod;
}
int isInInterval(int left, int right, int index)
{
if (left <= index && index <= right)
return 1;
return 0;
}
void freeTree(Node **root)
{
if (*root == null)
return;
freeTree(&((*root) -> left));
freeTree(&((*root) -> right));
free(*root);
}
int buildTree(Node **root, int left_number, int right_number, int *array)
{
if (*root == null)
{
*root = new_node();
}
if(left_number == right_number)
{
(*root) -> max = array[left_number];
(*root) -> left_number = left_number;
(*root) -> right_number = right_number;
(*root) -> left = null;
(*root) -> right = null;
return array[left_number];
}
else
{
(*root) -> left = new_node();
(*root) -> right = new_node();
(*root) -> left_number = left_number;
(*root) -> right_number = right_number;
(*root) -> max = max(buildTree(&((*root) -> left), left_number, left_number + (right_number - left_number) / 2, array),
buildTree(&((*root) -> right), left_number + (right_number - left_number) / 2 + 1, right_number, array));
return (*root) -> max;
}
}
void DFS(Node *root)
{
if (root == null)
return ;
printf("[%d - %d] : %d\n", root -> left_number, root -> right_number, root -> max);
if (root -> left != null)
DFS(root -> left);
if (root -> right != null)
DFS(root -> right);
}
int updateTree(Node **root, int index_element, int *array)
{
if ((*root) -> left_number == index_element && (*root) -> right_number == index_element)
{
(*root) -> max = array[index_element];
return array[index_element];
}
if (isInInterval((*root) -> left_number, (*root) -> right_number, index_element) == 0)
return (*root) -> max;
else
{
(*root) -> max = max(updateTree(&((*root) -> left), index_element, array),
updateTree(&((*root) -> right), index_element, array));
return (*root) -> max;
}
}
int IntervalIsInInterval(int left, int right, int left_number, int right_number)
{
if (left <= left_number && right_number <= right && left_number <= right_number)
return 1;
return 0;
}
int querryTree(Node *root, int left_number, int right_number)
{
if (root -> left_number == left_number && root -> right_number == right_number)
return root -> max;
else
{
int middle = root -> left_number + (root -> right_number - root -> left_number) / 2;
if (IntervalIsInInterval(root -> left_number, middle, left_number, right_number) == 1)
return querryTree(root -> left, left_number, right_number);
else if (IntervalIsInInterval(middle + 1, root -> right_number, left_number, right_number) == 1)
return querryTree(root -> right, left_number, right_number);
else if (IntervalIsInInterval(root -> left_number, root -> right_number, left_number, right_number) == 1)
return max(querryTree(root -> left, left_number, middle), querryTree(root -> right, middle + 1, right_number));
}
}
int main(int argc, char const *argv[])
{
int N, M;
FILE *read = fopen("arbint.in", "r");
FILE *write = fopen("arbint.out", "w");
fscanf(read, "%d%d", &N ,&M);
int *array = (int *) calloc (N + 1, sizeof(int));
for (int i = 1; i <= N; i++)
fscanf(read, "%d", &array[i]);
Node *root = null;
buildTree(&root, 1, N, array);
int type, a, b;
for (int i = 0; i < M; i++)
{
fscanf(read, "%d%d%d", &type, &a, &b);
if (type == 0)
fprintf(write, "%d\n", querryTree(root, a, b));
else
{
array[a] = b;
updateTree(&root, a, array);
}
}
free(array);
fclose(read);
fclose(write);
return 0;
}