Pagini recente » Cod sursa (job #3219437) | Cod sursa (job #1500269) | Cod sursa (job #2256826) | Cod sursa (job #2394957) | Cod sursa (job #2312461)
/*
* 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;
int spacing = logn;
while(spacing > 0 && (1 << spacing) >= dist) spacing--;
//fprintf(stderr, "[%d, %d] cu log(%d)=%d -> iau [%d,%d] si [%d,%d]\n",
// st, dr, dist, spacing, st, st+(1<<spacing)-1, dr - (1<<spacing) + 1, dr - (1<<spacing) + 1 + (1<<spacing)-1);
return Min(mintable[spacing][st], mintable[spacing][dr - (1<<spacing) + 1]);
}
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;
}