Pagini recente » Cod sursa (job #1785631) | Cod sursa (job #764577) | Cod sursa (job #875357) | Cod sursa (job #1206200) | Cod sursa (job #2844921)
#include <iostream>
#include <fstream>
using namespace std;
ifstream in("rmq.in");
ofstream out("rmq.out");
/**
I. precalculari pe bucati de sqrt(n)
i 1 2 3 4 5 6 7 8 9 10
a[i] 2 4 3 |1 6 7 |
M[1]=1 M[2]=4 etc
query pe (x,y) -> portiunile intregi de sqrt(n) + resturile pana la
x, y parcurse
O( N + sqrt(N)*M )
II. matrice precalculata total
m[i][j] = minimul din (a[i], .. a[j])
m[i][j] = min( m[i][j-1], a[i][j] )
O(N^2)
SPARSE TABLE ALGORITHM (topcoder)
m[i][j] = indicele minimului din secventa care incepe la i si are
2^j elemente: a[i], a[i+1], ... a[i + 2^j - 1]
relatia de recurenta: (impartim secv de 2^j in 2 de 2^j-1
m[i][j] = min( m[i][j-1], m[i + 2^j-1][j-1] )
pentru query-uri de lungimi care nu sunt putere de 2:
2 intervale de putere a lui 2 <= lungimea secv
se vor suprapune, dar nu conteaza pentru minim
se precalculeaza si puterea maxima pt fiecare numar de la 1 la n
*/
int a[100050];
int m[100050][25];
int log[100050];
int main()
{
int n, mm;
in>>n>>mm;
/// valoarea minima
for( int i=1; i<=n; i++ ){
in>>a[i];
m[i][0]=a[i];
}
/// PRECALCULARE
log[1]=0;
for( int i=2; i<=n; i++ ){
log[i] = 1 + log[i/2];
}
for( int j=1; (1<<j)<=n; j++ ){ /// lungimea
for( int i=1; i + (1<<j) - 1 <= n; i++ ){ /// pozitia de inceput
m[i][j] = min( m[i][j-1], m[i + 1<<(j-1) ][j-1] );
}
}
int x, y;
for( int i=1; i<=mm; i++ ){
in>>x>>y;
/// 2^p <= y-x+1, p maxim
/// p = log2 (y-x+1)
int p = log[y-x+1];
int rez = min( m[x][p], m[y - (1<<p)+1][p] );
out<<rez<<'\n';
}
return 0;
}