Cod sursa(job #1234815)

Utilizator andreioneaAndrei Onea andreionea Data 28 septembrie 2014 01:51:52
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.28 kb
#include <fstream>
#include <vector>
#include <algorithm>

struct Node{
    int left, right;
    unsigned long val;
    Node* p_left, *p_right;
    Node(int, int, const std::vector<unsigned long>&);
    void Switch(int, unsigned long);
    unsigned long GetMax(int, int);
    ~Node();
};

Node::Node(int left, int right, const std::vector<unsigned long>& vect):
    left(left), right(right), val(0), p_left(0), p_right(0)
{
    if (left == right) {
    val = vect[left];
    p_left = p_right = 0;
    }
    else if (left < right) {
        int mid = (left + right) / 2;
        p_left = new Node(left, mid, vect);
        p_right = new Node(mid + 1, right, vect);
        val = std::max(p_left->val, p_right->val);
    }
}

Node::~Node()
{
    if (p_left) {
        delete p_left;
        p_left = 0;
    }
    if (p_right){
        delete p_right;
        p_right = 0;
    }
}

void Node::Switch(int pos, unsigned long x)
{
    if ((left == right) && (left == pos)) {
        val = x;
    }
    else if (left != right){
        int mid = (left + right) / 2;
        if (pos <= mid) {
            p_left->Switch(pos, x);
        }
        else {
            p_right->Switch(pos, x);
        }
            val = std::max(p_left->val, p_right->val);
    }
}

unsigned long Node::GetMax(int a, int b)
{
    unsigned long rez = 0;
    if ((left == right) || ((a <= left) && (right <= b)))
        return val;
    int mid = (left + right) / 2;
    if (a <= mid) {
        unsigned long x = p_left->GetMax(a, std::min(mid, b));
        rez = std::max(x, rez);
    }
    if (b > mid) { 
        unsigned long x = p_right->GetMax(std::max(a, mid+1), b);
        rez = std::max(x, rez);
    }
    return rez;
}

int main()
{
    std::ifstream f("arbint.in");
    std::ofstream g("arbint.out");
    int N, M;
    f >> N >> M;
    std::vector<unsigned long> v;
    v.reserve(N);
    for (int i = 0; i < N; ++i){
        unsigned long x;
        f >> x;
        v.push_back(x);
    }
    Node arb(0, N - 1, v);
    for (int i = 0; i < M; ++i) {
        unsigned long op, a, b;
        f >> op >> a >> b;
        if (op == 0) {
            unsigned long x = arb.GetMax(a - 1, b - 1);
            g << x << "\n";
        }
        else if (op == 1) {
            arb.Switch(a - 1, b);
        }
    }
    f.close();
    g.close();
    return 0;
}