Pagini recente » Cod sursa (job #462408) | Cod sursa (job #141078) | Cod sursa (job #1358823) | Cod sursa (job #1705478) | Cod sursa (job #3161436)
#include <bits/stdc++.h>
using namespace std;
ifstream in("rmq.in");
ofstream out("rmq.out");
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
#define fi first
#define se second
#define NMAX 100005
#define MOD 1000000007
#define INF 0x3f3f3f3f
int n, m, v[NMAX], st[18][NMAX]; //st = sparse table nu segment tree :3
//st[i][j] = minimul din intervalul j....2^i, deci dintr-un interval de 2^i elemente care incepe in j
void read() {
in>>n>>m;
for (int i=1; i<=n; i++)
in>>st[0][i];
}
void buildST() {
for (int i=1, k=1; k<=n; i++, k*=2) //k=2^(i-1);
for (int j=1; j+k<=n; j++) //j+k adica pozitia maxima de unde incepe sa nu iasa din vector
//un interval de 2^i care pleaca din j va fi minimul din intervalele de mai sus
//cel din j care merge 2^(i-1) (j, j+1, .., j+2^(i-1)-1)
// si urmatorul tot de 2^(i-1) elemente ca adunate sa fie de 2^i elemente
//al doilea va fi unde se termina cel anteiror+1, adica de la j+2^(i-1), adica de la j+k mergand 2^(i-1) elem.
st[i][j] = min(st[i-1][j], st[i-1][j+k]);
}
void solve()
{
buildST();
for (int i=1; i<=m; i++)
{
int x, y;
in>>x>>y;
int log2 = __builtin_clz(y-x+1); //0-urile din stanga primului 1
log2 = 31-log2; //logaritmul in baza 2(int floor) este unde se afla primul 1, de ex in ..0000110 avem 31-29 = 2
int pow = 1<<log2; //2^log2
out<<min(st[log2][x], st[log2][y-(pow-1)])<<'\n';
//merg 2^log2 incepand din x, iar apoi mai am sa merg din y-2^log2 la y ]
//fiindca intervalul e complet sau incomplet in 2^log2, y-(2^log2-1) va fi >=x+2^log2
//deci nu va scadea mai jos de x si va merge exact pana in y fiindca merg 2^log2
}
}
int main()
{
read();
solve();
return 0;
}