Cod sursa(job #3233835)

Utilizator tmaxmaxTeodor Maxim tmaxmax Data 5 iunie 2024 02:00:06
Problema Arbori de intervale Scor 100
Compilator c-64 Status done
Runda Arhiva educationala Marime 3.03 kb
#include <assert.h>
#include <stdio.h>

typedef struct Node {
    int a, b;
    int max;
    struct Node *smaller, *greater;
} Node;

#define MAX_INPUT_SIZE 100000

Node pool[2 * MAX_INPUT_SIZE];
int pool_next;

Node *node_get(int a, int b, int max) {
    Node *n = &pool[pool_next++];
    n->a = a;
    n->b = b;
    n->max = max;
    return n;
}

Node *tree_build(const int *v, int start, int end) {
    if (start == end) {
        return node_get(start, end, v[start]);
    }

    int mid = start + (end - start) / 2;

    Node *smaller = tree_build(v, start, mid);
    Node *greater = tree_build(v, mid + 1, end);

    int max = smaller->max;
    if (greater->max > max) {
        max = greater->max;
    }

    Node *n = node_get(start, end, max);
    n->smaller = smaller;
    n->greater = greater;

    return n;
}

Node *tree_update(Node *root, int pos, int val) {
    if (root == NULL) {
        return node_get(pos, pos, val);
    }

    if (root->a == root->b) {
        root->max = val;
        return root;
    }

    if (pos <= root->smaller->b) {
        root->smaller = tree_update(root->smaller, pos, val);
    } else {
        root->greater = tree_update(root->greater, pos, val);
    }

    root->max = root->smaller->max;
    if (root->greater->max > root->max) {
        root->max = root->greater->max;
    }

    return root;
}

// void tree_inorder(Node *root, int indent) {
//     if (root == NULL) {
//         return;
//     }

//     tree_inorder(root->smaller, indent + 1);

//     for (int i = 0; i < indent; i++) {
//         printf("  ");
//     }
//     printf("[%d, %d] %d\n", root->a, root->b, root->max);

//     tree_inorder(root->greater, indent + 1);
// }

const int *tree_query(Node *root, int a, int b) {
    // printf("[%d, %d] %d (%d, %d)\n", root->a, root->b, root->max, a, b);

    if (root == NULL) {
        return NULL;
    }

    if (a <= root->a && root->b <= b) {
        return &root->max;
    }

    const int *found_smaller = NULL;
    if (a <= root->smaller->b) {
        found_smaller = tree_query(root->smaller, a, b);
    }

    const int *found_greater = NULL;
    if (b >= root->greater->a) {
        found_greater = tree_query(root->greater, a, b);
    }

    if (found_smaller == NULL) {
        return found_greater;
    }
    if (found_greater == NULL) {
        return found_smaller;
    }
    if (*found_smaller > *found_greater) {
        return found_smaller;
    }
    return found_greater;
}

int main(void) {
    freopen("arbint.in", "r", stdin);
    freopen("arbint.out", "w", stdout);

    int n, m;
    scanf("%d %d", &n, &m);

    int v[MAX_INPUT_SIZE];
    for (int i = 0; i < n; i++) {
        scanf("%d", v + i);
    }

    Node *root = tree_build(v, 0, n - 1);

    int kind, a, b;
    for (int i = 0; i < m; i++) {
        scanf("%d %d %d", &kind, &a, &b);

        if (kind == 0) {
            printf("%d\n", *tree_query(root, a - 1, b - 1));
        } else if (kind == 1) {
            root = tree_update(root, a - 1, b);
            // tree_inorder(root, 0);
        }

        // printf("\n");
    }

    return 0;
}