Cod sursa(job #1414723)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 2 aprilie 2015 22:27:21
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.97 kb
#include <bits/stdc++.h>

using namespace std;

const int Nmax = 100000 + 1;

struct Node
{
    int maxim;
    Node *l, *r;

    explicit Node() : maxim(0), l(NULL), r(NULL) {
    }
};

Node *roots[Nmax];
int v[Nmax];
int N, M;

Node* build(int st, int dr)
{
    Node *node = new Node();

    if (st == dr)
        node->maxim = v[st];
    else
    {
        int m = (st + dr) / 2;

        node->l = build(st, m);
        node->r = build(m + 1, dr);

        node->maxim = max(node->l->maxim, node->r->maxim);
    }

    return node;
}

Node* create(Node *root, int st, int dr, int pos, int key)
{
    Node *node = new Node();

    if (st == dr)
        node->maxim = key;
    else
    {
        int m = (st + dr) / 2;

        if (pos <= m)
            node->l = create(root->l, st, m, pos, key);
        else
            node->l = root->l;

        if (m < pos)
            node->r = create(root->r, m + 1, dr, pos, key);
        else
            node->r = root->r;

        node->maxim = max(node->l->maxim, node->r->maxim);
    }

    return node;
}

int query(Node *root, int st, int dr, int st_q, int dr_q)
{
    if (st_q <= st && dr <= dr_q)
        return root->maxim;
    else
    {
        int m = (st + dr) / 2;
        int sol = numeric_limits<int>::min();

        if (st_q <= m)
            sol = max(sol, query(root->l, st, m, st_q, dr_q));

        if (m < dr_q)
            sol = max(sol, query(root->r, m + 1, dr, st_q, dr_q));

        return sol;
    }
}

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

    in >> N >> M;

    for (int i = 1; i <= N; ++i)
        in >> v[i];

    roots[0] = build(1, N);
    int currentRoot = 0;

    for (int i = 1; i <= M; ++i)
    {
        int tip, a, b;
        in >> tip >> a >> b;

        if (tip == 0)
            out << query(roots[currentRoot], 1, N, a, b) << "\n";
        else
        {
            roots[currentRoot + 1] = create(roots[currentRoot], 1, N, a, b);
            currentRoot++;
        }
    }

    return 0;
}