Pagini recente » documentatie/arhiva-educationala | Cod sursa (job #645997) | Cod sursa (job #3203252) | Cod sursa (job #183188) | Cod sursa (job #3185820)
#include <fstream>
using namespace std;
ifstream f("rmq.in");
ofstream g("rmq.out");
/// Arbori de intervale - complexitate O(log n) per query
/// RMQ - putem folosi cand nu avem update-uri, cand intervalele se pot intersecta fara sa incurce
/// rezultatul si avem O(1) per query, O(n log n) la constructie
int n, m, x, y, l;
int k[100005], kcurent;
int rmq[100005][25]; /// rmq[n][log n]
int v[100005];
void create_rmq() {
for (int j = 0; (1 << j) <= n; j++) {
for (int i = 1; i + (1 << j) - 1 <= n; i++) {
if (j == 0) {
rmq[i][j] = v[i];
}
else {
rmq[i][j] = min(rmq[i][j - 1], rmq[i + (1 << (j - 1))][j - 1]);
}
}
}
}
void solve() {
/// precalculam pentru fiecare lungime posibila de interval (de la 1 la n)
/// care este cel mai mare k, astfel incat 2^k < lungime
for (int i = 2; i <= n; i++) {
k[i] = k[i - 1];
if ((1 << (k[i] + 1)) < i) {
k[i]++;
}
}
for (int t = 1; t <= m; t++) {
f >> x >> y;
l = y - x + 1; /// lungimea intervalului
g << min(rmq[x][k[l]], rmq[y-(1<<k[l])+1][k[l]]) << '\n';
}
}
int main()
{
f >> n >> m;
for (int i = 1; i <= n; i++) {
f >> v[i];
}
create_rmq();
solve();
}