#include <stdio.h>
#include <malloc.h>
typedef struct TreeNode {
int LowLimit, HighLimit, MaxElement;
struct TreeNode *leftNode;
struct TreeNode *rightNode;
} BinarySearchTree;
BinarySearchTree* InitializeNodes(BinarySearchTree* TreeRoot, int LowLimit, int HighLimit, int* NodeArray) {
//out-of-bounds
if(LowLimit > HighLimit) {
return NULL;
}
//Match
if(LowLimit == HighLimit) {
TreeRoot = (BinarySearchTree *) malloc(sizeof(BinarySearchTree));
TreeRoot->LowLimit = LowLimit;
TreeRoot->HighLimit = HighLimit;
TreeRoot->leftNode = NULL;
TreeRoot->rightNode = NULL;
return TreeRoot;
} else {
TreeRoot = (BinarySearchTree *) malloc(sizeof(BinarySearchTree));
TreeRoot->leftNode = (BinarySearchTree *) malloc(sizeof(BinarySearchTree));
TreeRoot->rightNode = (BinarySearchTree *) malloc(sizeof(BinarySearchTree));
TreeRoot->LowLimit = LowLimit;
TreeRoot->HighLimit = HighLimit;
TreeRoot->leftNode = InitializeNodes(TreeRoot->leftNode, LowLimit, (LowLimit + HighLimit) / 2, NodeArray);
TreeRoot->rightNode = InitializeNodes(TreeRoot->rightNode, (LowLimit + HighLimit) / 2 + 1, HighLimit, NodeArray);
return TreeRoot;
}
}
int maxNode(int Node1, int Node2) {
return (Node1 > Node2) ? Node1 : Node2;
}
BinarySearchTree* UpdateMethod(BinarySearchTree* TreeRoot, int position, int value) {
if(TreeRoot->LowLimit == TreeRoot->HighLimit && TreeRoot->LowLimit == position) {
TreeRoot->MaxElement = value;
return TreeRoot;
}
int middlePoint = (TreeRoot->LowLimit + TreeRoot->HighLimit) / 2;
if(position <= middlePoint) {
TreeRoot->leftNode = UpdateMethod(TreeRoot->leftNode, position, value);
} else {
TreeRoot->rightNode = UpdateMethod(TreeRoot->rightNode, position, value);
}
TreeRoot->MaxElement = maxNode(TreeRoot->leftNode->MaxElement, TreeRoot->rightNode->MaxElement);
return TreeRoot;
}
void QueryBinaryTree(BinarySearchTree* TreeRoot, int lowLimit, int highLimit, int *maxArray) {
if(TreeRoot == NULL) {
return ;
}
if(lowLimit <= TreeRoot->LowLimit && highLimit <= TreeRoot->HighLimit) {
(*maxArray) = maxNode((*maxArray), TreeRoot->MaxElement);
return ;
}
int middlePoint = (TreeRoot->LowLimit + TreeRoot->HighLimit) / 2;
if(lowLimit <= middlePoint) {
QueryBinaryTree(TreeRoot->leftNode, lowLimit, highLimit, maxArray);
} else if(middlePoint < highLimit) {
QueryBinaryTree(TreeRoot->rightNode, lowLimit, highLimit, maxArray);
}
}
void FreeNode(BinarySearchTree *TreeRoot) {
if(TreeRoot == NULL) {
return ;
}
FreeNode(TreeRoot->leftNode);
FreeNode(TreeRoot->rightNode);
TreeRoot = NULL;
free(TreeRoot);
}
int main() {
freopen("arbint.in","r",stdin);
freopen("arbint.out","w",stdout);
int lengthArray, *array = NULL, a, b, option, opNumber, maxN;
scanf("%d %d", &lengthArray, &opNumber);
array = (int *) malloc(lengthArray * sizeof(int));
for(int index = 0; index < lengthArray; ++index) {
scanf("%d", (array + index));
}
BinarySearchTree* IntervalTree = NULL;
IntervalTree = InitializeNodes(IntervalTree, 0, lengthArray - 1, array);
for(int index = 0; index < opNumber; ++index) {
scanf("%d %d %d", &option, &a, &b);
if(option == 0) {
QueryBinaryTree(IntervalTree, a - 1, b - 1, &maxN);
printf("%d\n", maxN);
} else {
IntervalTree = UpdateMethod(IntervalTree, a - 1, b);
}
}
FreeNode(IntervalTree);
return 0;
}