Pagini recente » Cod sursa (job #3351863) | Cod sursa (job #133544) | Cod sursa (job #790157)
Cod sursa(job #790157)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <deque>
using namespace std;
ifstream f("rmq.in");
ofstream g("rmq.out");
#define nmax 100005
#define inf (1<<29)
#define ll long long
int n, m, a[nmax], Min[17][nmax], Exp[nmax];
void citeste(){
f >> n >> m;
for(int i=1; i<=n; ++i) f >> a[i];
}
void preprocesare(){
//initializez
//am intervalul i,i+2^0-1;
for(int i=1; i<=n; ++i) Min[0][i] = a[i];
for(int i=1; i<=17; ++i){
//nu are rost sa ma duc pana la n; trebuie respectata conditia j + 2^i - 1 <= n => ca j <= (n- 2^i +1)
for(int j=1; j<=n-(1<<i)+1; ++j){
int unde = j + (1<<i)-1;//intervalul ocupat de pozitia j; adica intervalul [j, j+(1<<i)-1];
int tata = unde - (1<<(i-1)) + 1;//
//deci eu dublez intervalul curent(adaugand o putere a lui doi);
//pot ramane la minimul de pana acum sau sa iau minimul de pe intervalul [j + (1<<(i-1))-1, j+(1<<i)-1]
Min[i][j] = min(Min[i-1][j], Min[i-1][tata]);
}
}
}
void rezolva(){
//minimul de pe intervalul [x,y]; imi preprocesez o matrice Min[i][j] = minimul de pe intervalul [j, j+(2^i)-1]
//+imi preprocesez un vector Exp[poz] = k; cel mai mare k a. i. 2^k <= poz;
preprocesare();
Exp[1] = 0;
for(int i=2; i<=n; ++i){
Exp[i] = Exp[i/2] + 1;
}
for(int i=1; i<=m; ++i){
int x,y;
f >> x >> y;
//ideea e sa impart acest interval in 2 intervale de puteri ale lui 2 (pt complexitataea o(1) )
//aflu cel mai mare k a. i. x + 2^k-1 <= y;
//aflu lungimea intervalului si acum trebuie sa caut un maxim k a. i. 2^k-1 <= lungime
int lung = y-x+1;
int k = Exp[lung];//cel mai mare k a. i. 2^k-1 <= lung;
//aflu minimul de pe intervalul [x, x+(2^k)-1]
int rez = inf;
rez = min(rez, Min[k][x]);
//aflu minimul de pe intervalul; Fie Y = x + ceva; acum trebuie sa gasesc acel ceva a. i. Y + (2^k) - 1 == y;
//=> ceva = y - (2^k) + 1;
int new_X = y - (1<<k)+1;
rez = min(rez, Min[k][new_X]);
g << rez << "\n";
}
}
int main(){
citeste();
rezolva();
f.close();
g.close();
return 0;
}