Pagini recente » Cod sursa (job #501375) | Cod sursa (job #2800762) | Cod sursa (job #1438186) | Cod sursa (job #884514) | Cod sursa (job #3137078)
#include <stdio.h>
#include <stdlib.h>
struct IntervalNode {
int low;
int high;
int max;
struct IntervalNode* left;
struct IntervalNode* right;
};
// Crea un nuevo nodo del árbol de intervalo con los límites especificados
struct IntervalNode* newNode(int low, int high) {
struct IntervalNode* node = (struct IntervalNode*)malloc(sizeof(struct IntervalNode));
node->low = low;
node->high = high;
node->max = 0;
node->left = NULL;
node->right = NULL;
return node;
}
// Construye el árbol de intervalo recursivamente
struct IntervalNode* buildIntervalTree(int arr[], int start, int end) {
if (start > end) {
return NULL;
}
struct IntervalNode* root = newNode(start, end);
if (start == end) {
root->max = arr[start];
return root;
}
int mid = (start + end) / 2;
// Construye los hijos izquierdo y derecho
struct IntervalNode* leftChild = buildIntervalTree(arr, start, mid);
struct IntervalNode* rightChild = buildIntervalTree(arr, mid + 1, end);
root->left = leftChild;
root->right = rightChild;
root->max = (leftChild->max > rightChild->max) ? leftChild->max : rightChild->max;
return root;
}
// Realiza una consulta de máximo en el árbol de intervalo
int queryMax(struct IntervalNode* root, int start, int end) {
if (root == NULL || end < root->low || start > root->high) {
return 0;
}
if (start <= root->low && end >= root->high) {
return root->max;
}
// Realiza una búsqueda recursiva en los hijos izquierdo y derecho
int leftMax = queryMax(root->left, start, end);
int rightMax = queryMax(root->right, start, end);
return (leftMax > rightMax) ? leftMax : rightMax;
}
// Actualiza el valor de un elemento en el árbol de intervalo
void updateElement(struct IntervalNode* root, int index, int newValue) {
if (root == NULL || index < root->low || index > root->high) {
return;
}
if (root->low == root->high && root->low == index) {
root->max = newValue;
return;
}
// Realiza una búsqueda recursiva para encontrar el nodo correspondiente al índice y actualiza su valor
updateElement(root->left, index, newValue);
updateElement(root->right, index, newValue);
root->max = (root->left->max > root->right->max) ? root->left->max : root->right->max;
}
int main() {
int N, M;
FILE *inputFile;
FILE *outputFile;
// Abre el archivo de entrada en modo lectura y el archivo de salida en modo escritura
inputFile = fopen("arbint.in", "r");
outputFile = fopen("arbint.out", "w");
// Lee el tamaño del vector N y el número de operaciones M desde el archivo de entrada
fscanf(inputFile, "%d %d", &N, &M);
int arr[N];
// Lee los elementos del vector desde el archivo de entrada
for (int i = 0; i < N; i++) {
fscanf(inputFile, "%d", &arr[i]);
}
// Construye el árbol de intervalo
struct IntervalNode* root = buildIntervalTree(arr, 0, N - 1);
// Procesa las operaciones
for (int i = 0; i < M; i++) {
int op, a, b;
fscanf(inputFile, "%d %d %d", &op, &a, &b);
if (op == 0) {
// Realiza una consulta de máximo en el intervalo [a, b]
int maxVal = queryMax(root, a - 1, b - 1);
// Escribe el resultado en el archivo de salida
fprintf(outputFile, "%d\n", maxVal);
} else if (op == 1) {
// Actualiza el elemento en la posición a con el valor b
updateElement(root, a - 1, b);
}
}
// Cierra los archivos de entrada y salida
fclose(inputFile);
fclose(outputFile);
return 0;
}