Cod sursa(job #3233825)

Utilizator tmaxmaxTeodor Maxim tmaxmax Data 5 iunie 2024 01:29:55
Problema Arbori de intervale Scor 0
Compilator c-64 Status done
Runda Arhiva educationala Marime 2.24 kb
#include <assert.h>
#include <stdio.h>

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

#define MAX_INPUT_SIZE 10000

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;
}

const int *tree_query(Node *root, int a, int b) {
    if (root == NULL) {
        return NULL;
    }

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

    if (root->smaller->b >= a) {
        return tree_query(root->smaller, a, b);
    }

    return tree_query(root->greater, a, b);
}

int main(void) {
    FILE *in = fopen("lgput.in", "r");
    FILE *out = fopen("lgput.out", "w");

    int n, m;
    fscanf(in, "%d %d", &n, &m);

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

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

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

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

    fclose(in);
    fclose(out);

    return 0;
}