Cod sursa(job #1585699)

Utilizator dm1sevenDan Marius dm1seven Data 31 ianuarie 2016 13:02:30
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.62 kb
#include <iostream>
#include <fstream>
using namespace std;
#include <algorithm>
#include <utility>
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <map>
#include <set>
#include <stack>
#include <chrono>
using namespace std::chrono;

typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vint;
typedef vector<vint> vvint;
typedef vector<ll> vll;
typedef vector<vll> vvll;
typedef vector<vvll> vvvll;
typedef vector<ull> vull;
typedef vector<vull> vvull;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef pair<ll, ll> pll;
typedef vector<pll> vpll;

#define fs first
#define sc second
#define pb push_back
// forward strict for, most common
#define fors(i, a, n) for (int i = (int) (a); i < (int) (n); ++i)
// forward inclusive for
#define fori(i, a, n) for (int i = (int) (a); i <= (int) (n); ++i)
// backward for, inclusive
#define forb(i, n, a) for (int i = (int) n; i >= a; --i)

struct node {
    int x, lr, rr;
    node(int x = 0, int lr = 0, int rr = 0) : x(x), lr(lr), rr(rr) {} 
};

class Problem {
public:
    // levels [0..L-1]
    int n, m, L, n2;
    //n2 = 2^(L-1);
    vector<node> heap;
    
    void solve() {
        ifstream ifs("arbint.in");
        ofstream ofs("arbint.out");

        ifs >> n >> m;
        L = (int) log2(n + 1);
        if ((1 << L) < n + 1) L++;
        n2 = 1 << L;
        heap.resize(2 * n2);
        fors(i, 0, n)
        {
            int b;
            ifs >> b;
            update_heap(n2 + i, b);
        }
        
        fill_ranges(1);
        // print_heap();

        fors(m_, 0, m)
        {
            int o, a, b;
            ifs >> o >> a >> b;
            if (o == 1) {
                update_heap(n2 + a - 1, b);                
                // print_heap();
                // printf("heap[%d] = %d\n", a, b);
            }
            else if (o == 0) {
                int mab = find_max(a, b);
                ofs << mab << "\n";
                //printf("max(%d, %d) = %d\n\n", n2 + a - 1, n2 + b - 1, mab);
            }
        }
    }

    int find_max(int a, int b)
    {
        int so = n2 + a - 1, e = n2 + b - 1;
        int s = so;
        int m = heap[s].x;
        while (s <= e)
        {
            // find a parent
            int i = s;
            // cout << "s = " << s << ", ";
            while (i != 1 && so <= heap[parent(i)].lr && heap[parent(i)].rr <= e) i = parent(i);
            m = max(m, heap[i].x);
            s = heap[i].rr + 1;
        }
        
        return m;
    }
    
    void fill_ranges(int i)
    {
        if (i >= n2) heap[i].lr = heap[i].rr = i;
        else {
            fill_ranges(chl(i));
            fill_ranges(chr(i));
            heap[i].lr = heap[chl(i)].lr;
            heap[i].rr = heap[chr(i)].rr;
        }
    }
    
    // i is a leaf node, b is it's value
    void update_heap(int i, int b) {
        heap[i].x = b;
        while (i != 1) {
            i = parent(i);
            heap[i].x = max(heap[chl(i)].x, heap[chr(i)].x);
        }
    }

    void print_heap() {
        fori(l, 0, L)
        {
            int c = 1 << l;
            fors(i, 0, c)
                cout << heap[c + i].x << " ";
            cout << endl;
        }
//        cout << endl;
    }

    // left child
    int chl(int i) {
        return 2 * i;
    }
    // right child
    int chr(int i) {
        return 2 * i + 1;
    }
    // parent
    int parent(int i) {
        return i / 2;
    }
};

int main() {
    Problem p;
    p.solve();
    return 0;
}