Cod sursa(job #3269074)

Utilizator PiciuAndreiAlinPiciu Andrei Alin PiciuAndreiAlin Data 18 ianuarie 2025 10:49:42
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.41 kb
#include <bits/stdc++.h>
using namespace std;

/**
rmq[i][j] = valoarea minima din intervalul [j, j+2^i-1]

Date initiale
rmq[0][i] = a[i], i=1..n
rmq[1][1] = min(a[1], a[2]) = min(rmq[0][1], rmq[0][2])

rmq[i][j] = min(rmq[i-1][j],   rmq[i-1][j+2^(i-1)])
               [j,j+2^(i-1)-1]  [j+2^(i-1),j+2^i-1]

Vrem sa stim:
1. pentru un i, cat este 2^i
2. Pentru un interval de lungime x, care este exponentul maxim e
  cu prop. ca 2^e <= x
  (Pentru 2. construim vectorul e cu 2^e[i] <= i)
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
e =   0 1 1 2 2 2 2 3 3  3  3  3  3  3  3  4

*/

ifstream fin("rmq.in");
ofstream fout("rmq.out");
int n, m;
int rmq[18][100003];
int e[100003], L[20];
/// L[i] = 2^i

int main()
{
    int i, j, x, y, len;
    /// construim pe L
    L[0] = 1;
    for (i = 1; i <= 18; i++)
        L[i] = L[i - 1] * 2;
    /// construim e
    e[1] = 0;
    for (i = 2; i <= 100000; i++)
        e[i] = 1 + e[i / 2];
    fin >> n >> m;
    for (i = 1; i <= n; i++)
        fin >> rmq[0][i]; /// fin >> a[i]
    /// recurentele:
    for (i = 1; i <= e[n]; i++)
    {
        for (j = 1; j <= n - L[i] + 1; j++)
            rmq[i][j] = min(rmq[i-1][j], rmq[i-1][j+L[i-1]]);
    }
    for (i = 1; i <= m; i++)
    {
        fin >> x >> y;
        j = e[y - x + 1];
        len = L[j];
        fout << min(rmq[j][x], rmq[j][y - len + 1]) << "\n";
    }
    return 0;
}