Pagini recente » Cod sursa (job #48933) | Cod sursa (job #2285668) | Cod sursa (job #2395770) | Cod sursa (job #3000944) | Cod sursa (job #2312437)
/*
* Range Minimum Query
* https://infoarena.ro/problema/rmq
*
*/
#include <stdio.h>
inline int Min(int a, int b) {
return a < b ? a : b;
}
int n;
int logn;
int mintable[18][100001]; // un pic peste log n
/*
* E interesant un comm de pe infoarena care zice ca [18][100001] e mai bine
* decat [100001][18] pentru ca de obicei accesezi pozitii consecutive de pe
* aceeasi linie, nu linii diferite de la aceeasi coloana. Si cacheurilor le
* place cand ai chestiile pe care le accesezi des cat mai apropiate
*
*/
inline void rmq_init() {
for(int spacing=1; spacing < logn; spacing++) {
int lastjmp = 1 << (spacing-1);
for(int i=1; i<=n-lastjmp; i++) {
mintable[spacing][i] = Min(mintable[spacing-1][i], mintable[spacing-1][i + lastjmp]);
}
}
}
inline int rmq_query(int st, int dr) {
int dist = dr - st + 1, res = 999999999;
for(int spacing=logn; spacing>=0; spacing--) {
if(dist & (1 << spacing)) {
res = Min(res, mintable[spacing][st]);
st += 1 << spacing;
}
}
return res;
}
int main() {
freopen("rmq.in", "r", stdin);
freopen("rmq.out", "w", stdout);
int m;
scanf("%d%d", &n, &m);
for(int i=1; i<=n; i++) scanf("%d", &mintable[0][i]);
logn = 0;
while((1 << logn) <= n) logn++;
rmq_init();
for(int i=1; i<=m; i++) {
int st, dr;
scanf("%d%d", &st, &dr);
printf("%d\n", rmq_query(st, dr));
}
return 0;
}