Cod sursa(job #3226411)

Utilizator razvan242Zoltan Razvan-Daniel razvan242 Data 21 aprilie 2024 12:53:49
Problema Arbori de intervale Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.57 kb
#include <fstream>
#include <vector>

using namespace std;

ifstream fin("arbint.in");
ofstream fout("arbint.out");

const int NMAX = 1e6 + 1;
const int KMAX = 1e3 + 1;

int n, q;
int answer[KMAX], a[NMAX];
int blockSize;

int findBlockSize() {
    int left = 1, right = n;
    int mid, ans = 1;
    while (left <= right) {
        mid = (left + right) / 2;
        if (mid * mid <= n) {
            ans = mid;
            left = mid + 1;
        }
        else {
            right = mid - 1;
        }
    }
    return ans;
}

void update(int pos, int val) {
    a[pos] = val;

    int startBlock, endBlock;
    for (int block = 1; block * blockSize <= n; ++block) {
        startBlock = (block - 1) * blockSize + 1;
        endBlock = blockSize * block;
        if (startBlock <= pos && pos <= endBlock) {
            answer[block] = 0;
            for (int i = startBlock; i <= endBlock; ++i) {
                answer[block] = max(answer[block], a[i]);
            }
            break;
        }
    }
}

int query(int left, int right) {
    int maximumResult = 0;
    int lastLeftUpdated = 2e9, lastRightUpdated = 0;
    bool foundWholeBlock = false;

    int startBlock, endBlock;
    for (int block = 1; block * blockSize <= n; ++block) {
        startBlock = (block - 1) * blockSize + 1;
        endBlock = blockSize * block;

        if (left <= startBlock && endBlock <= right) {
            if (startBlock < lastLeftUpdated) {
                lastLeftUpdated = startBlock;
                foundWholeBlock = true;
            }
            if (endBlock > lastRightUpdated) {
                lastRightUpdated = endBlock;
                foundWholeBlock = true;
            }
            maximumResult = max(maximumResult, answer[block]);
        }

        if (endBlock > right) {
            break;
        }
    }

    if (!foundWholeBlock) {
        lastLeftUpdated = lastRightUpdated = right;
    }

    for (int i = left; i <= lastLeftUpdated; ++i) {
        maximumResult = max(maximumResult, a[i]);
    }
    for (int i = lastRightUpdated; i <= right; ++i) {
        maximumResult = max(maximumResult, a[i]);
    }
    return maximumResult;
}

int main() {
    fin >> n >> q;
    blockSize = findBlockSize();

    int block;
    for (int i = 1; i <= n; ++i) {
        fin >> a[i];
        block = (i - 1) / blockSize + 1;
        answer[block] = max(answer[block], a[i]);
    }

    int operation, x, y;
    while (q--) {
        fin >> operation >> x >> y;
        if (operation == 1) {
            update(x, y);
        }
        else {
            fout << query(x, y) << '\n';
        }
    }

    return 0;
}