Cod sursa(job #2774599)

Utilizator radu.z5Zamfirescu Radu Ioan radu.z5 Data 12 septembrie 2021 02:41:33
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.12 kb
#include <fstream>
#include <cmath>

using namespace std;

size_t leftChild(size_t node) {
    return (node << 1) + 1;
}

size_t rightChild(size_t node) {
    return (node << 1) + 2;
}

void buildIntervalTree(int *tree, int node, int *v, int a, int b) {
    tree[node] = v[a];
    if (a < b) {
        int mid = ((b - a) >> 1) + a;
        buildIntervalTree(tree, leftChild(node), v, a, mid);
        buildIntervalTree(tree, rightChild(node), v, mid + 1, b);
        tree[node] = max(tree[leftChild(node)], tree[rightChild(node)]);
    }
}

// leftBound e capatul stanga pentru informatia din intervalT[node]
// rightBound e capatul dreapta pentru informatia din intervalT[node]
// [a, b] e intervalul pentru care se face interogarea
int interogate(int *intervalT, size_t node, int leftBound, int rightBound,
            const int a, const int b) {
    if (a > b || (a <= leftBound && rightBound <= b)) {
        return intervalT[node];
    } else {
        int mid = ((rightBound - leftBound) >> 1) + leftBound;
        int leftMax, rightMax, both = 0;

        if (a <= mid) {
            leftMax = interogate(intervalT, leftChild(node), leftBound, mid,
                a, b);
            both |= 1;
        }
        if (mid < b) {
            rightMax = interogate(intervalT, rightChild(node), mid + 1,
                rightBound, a, b);
            both |= 2;
        }

        if (both == 3)
            return max(leftMax, rightMax);
        else if (both == 1)
            return leftMax;
        else if (both == 2)
            return rightMax;
        else
            return intervalT[node];
    }
}

// pentru problema data la actualizare intervalul [a, b] e mereu [idx, idx]
void update(int *intervalTree, size_t node, int leftBound, int rightBound,
            const int idx, const int newValue) {
    if (leftBound == idx && rightBound == idx) {
        intervalTree[node] = newValue;
    } else {
        int mid = ((rightBound - leftBound) >> 1) + leftBound;
        if (idx <= mid) {
            update(intervalTree, leftChild(node), leftBound, mid, idx,
                newValue);
        }
        if (mid < idx) {
            update(intervalTree, rightChild(node), mid + 1, rightBound, idx,
                newValue);
        }
        intervalTree[node] = max(intervalTree[leftChild(node)],
                            intervalTree[rightChild(node)]);
    }
}

int main(void) {
    ifstream in("arbint.in");
    ofstream out("arbint.out");

    int n, m, i;
    in >> n >> m;

    int v[n];

    for (i = 0; i < n; i++)
        in >> v[i];

    // k = [log2(n)] + 1
    int k = (int) ceil(log2((double) n));
    int treeCapacity = 1 << (k + 1);
    int intervalTree[treeCapacity];
    buildIntervalTree(intervalTree, 0, v, 0, n - 1);

    int f, a, b;
    for (i = 0; i < m; i++) {
        in >> f >> a >> b;
        if (f == 0)
            out << interogate((int *) intervalTree, 0, 0, n - 1, a - 1, b - 1)
                << '\n';
        else
            update((int *) intervalTree, 0, 0, n - 1, a - 1, b);
    }

    in.close();
    out.close();
    return 0;
}