Cod sursa(job #822594)

Utilizator ciorile.chioareBogatu Adrian ciorile.chioare Data 23 noiembrie 2012 19:55:35
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.27 kb
#include<cstdio>

FILE* in;
FILE* out;

//int iarb;
int *arbint;

int flog(int n)
{
        if(n == 1)
                return 0;
        return 1 + flog(n >> 1);
}

/* un wrapper la functia log pentru a returna [log(n)] + 1 */
int log(int n)
{
        return flog((n << 1) - 1);
}

int max(int a, int b)
{
        return (a < b)?b:a;
}

void afis(int* ceva, int s, int n, const char mess[]) {
        fprintf(stderr, "%s", mess);
        for(int i = s; i < n + s; ++i)
                fprintf(stderr, "%d ", ceva[i]);
        fprintf(stderr, "\n");
}

int make_arbint(int *a, int n, int iarb) {
        if(n < 1)
                return a[0];

        int x = make_arbint(a, n >> 1, (iarb << 1) + 1);
        int y = make_arbint(a + (n >> 1), n >> 1, (iarb << 1) + 2);
        arbint[iarb] = max(x, y);
        return arbint[iarb];
}

int find_max(int rad, int a, int b, int l, int r) {
        if((a <= l && r <= b))
                return arbint[rad];
        int mid = (l + r) / 2;
        if(b <= mid)
                return find_max(2 * rad + 1, a, b, l, mid);
        if(mid < a)
                return find_max(2 * rad + 2, a, b, mid + 1, r);
        else
                return max(find_max(2 * rad + 1, a, mid, l, mid), 
                                find_max(2 * rad + 2, mid + 1, b, mid + 1, r));
}

void update(int a, int b) {
        arbint[a] = b;
        while(a) {
                a = (a - 1) / 2;
                arbint[a] = max(arbint[2 * a + 1], arbint[2 * a + 2]);
        }
}

int main()
{

        in = fopen("arbint.in", "r");
        out = fopen("arbint.out", "w");

        int *A;
        int n, m;

        fscanf(in, "%d%d", &n, &m);

        /* marim vectorul pana la cea mai mica putere a lui 2 mai mare ca n */
        A = new int[1 << log(n)];

        for(int i = 0; i < n; ++i)
                fscanf(in, "%d", A + i);
        n = 1 << log(n);

        arbint = new int[n];
        int narb = 0;
        make_arbint(A, n, narb);
        narb = (n << 1) - 1;

        int op, a, b;
        for(int i = 0; i < m; ++i) {
                fscanf(in, "%d%d%d", &op, &a, &b);
                if(op == 0)
                        fprintf(out, "%d\n", find_max(0, a - 1, b - 1, 0, n - 1));
                else if(op == 1)
                        update(n - 2 + a, b);
        }

        return 0;
}