Cod sursa(job #672934)

Utilizator ukiandreaAndreea Lucau ukiandrea Data 3 februarie 2012 14:40:25
Problema Range minimum query Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.52 kb
#include <stdio.h>

int mins[525000];
int a[100000];

// We search the min for node, responsible for the interval [i1, i2]
void initialize(int node, int i1, int i2)
{
    if (i1 == i2) {
        mins[node] = i1;
        return;
    }

    // search the min for the two branches
    initialize(2 * node, i1, (i1 + i2) / 2);
    initialize(2 * node + 1, (i1 + i2) / 2 + 1, i2);

    // choose the min between the two
    mins[node] = (a[mins[2 * node]] < a[mins[2 * node + 1]]) ? mins[2 * node] : mins[2 * node + 1];
}

// Query for the min in [x, y] through <node>
int query(int node, int b, int e, int i, int j)
{
    // if [b, e] is outside the interval [x, y], return -1
    if (i > e || j < b)
        return -1;

    // if [b, e] is included in [i, j], return mins[node]
    if (i <= b && e <= j)
        return mins[node];

    if (b == e)
        return mins[b];

    int m1 = query(2 * node, b, (b + e) / 2, i, j);
    int m2 = query(2 * node + 1, (b + e) / 2 + 1, e, i, j);

    if (m1 == -1)
        return m2;

    if (m2 == -1)
        return m1;

    return (a[m1] < a[m2]) ? m1 : m2;
}

int main()
{
    int n, m;

    freopen("rmq.in", "r", stdin);
    freopen("rmq.out", "w", stdout);

    scanf("%d %d\n", &n, &m);

    for (int i = 0; i < 525000; i++)
        mins[i] = -1;

    for (int i = 0; i < n; i++) 
        scanf("%d\n", &a[i]);

    initialize(1, 0, n - 1);

    for (int i = 0; i < m; i++) {
        int x, y;
        scanf("%d %d\n", &x, &y);
        printf("%d\n", a[query(1, 0, n - 1, x - 1, y - 1)]);
    }

    return 0;
}