Cod sursa(job #3269083)

Utilizator GabrielPopescu21Silitra Gabriel - Ilie GabrielPopescu21 Data 18 ianuarie 2025 10:50:15
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.12 kb
#include <bits/stdc++.h>
using namespace std;

/**
a = a1 ... a100
min{[10, 60]} = min([10, 41], [42, 57], [58, 59], [60,60])
51 = 32 + 16 + 2 + 2^0

min([10, 41], [26, 57])

32 (2^5) < 51

            2^5 = 32
------------------------------
7         2^4      7+32-1 = 38
           22  23

32 = 2^4 + 2^4

rmq[5][7] = min(rmq[4][7], rmq[4][23])
                 [7,22] [23, 38]

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]

a = a1 a2 ... a18
i = 3; j = 1, 2, ..., 11
i = 4; j = 1, 2, 3

1 5 6 4 3
5 6 4 = [2,3] si [3, 4]

  |          len   |
x ................................ y
            |          len         |

j = e[y-x+1]
len = 16
rmq[j][x], rmq[j][y-len+1]


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;
}