Pagini recente » Cod sursa (job #1385787) | Cod sursa (job #1124718) | Cod sursa (job #1175163) | Cod sursa (job #490858) | Cod sursa (job #2753375)
#include<bits/stdc++.h>
using namespace std;
ifstream fin("rmq.in");
ofstream fout("rmq.out");
int n, m;
int a[18][100003];; ///a[i][j] --> minimul pe o lungime de 2^i elem ce incepe de pe poz j
///RMQ
void initializare()
{
int i, j, p;
//din curs:
//1 6 → min(min(1,4), min(3,6)) - prin urmare, putem face 2 query-uri
for(i = 1, p = 2; p <= n; ++i, p *= 2)/// p--> nu are rost sa cautam mai multi parinti decat sunt in total noduri
for(j = 0; j < n; ++j)
a[i][j] = min(a[i-1][j], a[i-1][j + p/2]);///"concatenam" cate 2 intervale si le facem minimul pe reuniune
}
int calc(int x, int y)
{
//calculam lungimea intervalului
int lg = y - x + 1;
///cautam cea mai mare putere a lui 2 apropiata de lg
int pow = 1, i = 0;
while(pow*2 < lg)
{
pow *= 2;
i++; ///exponentul puterii de 2
}
///acum stim ca putem sa sarim: peste o bucata de interval
///fiind minim intervalele se pot intrepatrunde
return min(a[i][x], a[i][y-pow+1]);
///in a[i][x] ---> cel mai mic elem din bucata de vector ce incepe pe poz x si are lg = 2^i
///a[i][y-pow+1] ....
///am imbunatatit cautarea
}
int main()
{
int x, y, i, j;
fin >> n >> m;
///initializam matriea de min
for( i=0; i<17; ++i)
for(j=0; j<100000; ++j)
a[i][j]=100005; //o valoare foarte mare nu va influenta minimul
for(j = 0; j < n; ++j)
fin>>a[0][j]; //elem minime pe o lungime de 2^0
initializare();
for( i = 1; i <= m; ++i)
{
fin >> x >> y; //cel mai mic elem pe intervalul [x, y]
fout << calc(x-1, y-1) << "\n";///indexare de la 0
}
}