Pagini recente » Cod sursa (job #761552) | Cod sursa (job #344513) | Cod sursa (job #2071069) | Cod sursa (job #821083) | Cod sursa (job #1127576)
// Include
#include <fstream>
using namespace std;
// Constante
const int sz = (int)1e5+1;
// Variabile
ifstream in("rmq.in");
ofstream out("rmq.out");
int num, questions;
int LG[sz]; // LG[i] e partea intreaga a logaritmului in baza 2 din i, precalculat
int RMQ[18][sz]; // RMQ[i][j] e minimul de pe intervalul ce incepe in j si are lungime 2^i
// Main
int main()
{
in >> num >> questions;
// Pe linia 0, lungimea intervalului va fi 2^0=1, deci inputul
for(int i=1 ; i<=num ; ++i)
in >> RMQ[0][i];
// Fiind puteri a lui 2, LG[i] este, mereu, cu 1 mai mare decat LG[i/2]
for(int i=2 ; i<=num ; ++i)
LG[i] = LG[i/2] + 1;
// Construiesc matricea, linie cu linie, prin calcularea minimului dintre 2 intervale cu lungimi egale si cu lungimea
// egala cu jumatate din lungimea intervalului curent (lungimile, fiind puteri ale lui 2, vor fi pe linii consecutive)
for(int i=1 ; 1<<i<=num ; ++i)
// La sfarsitul liniei, capatul din dreapta al intervalului va depasi numarul de elemente, asa ca ma oproesc mai repede
for(int j=1 ; j<=num-(1<<i)+1; ++j)
RMQ[i][j] = min(RMQ[i-1][j], RMQ[i-1][j+(1<<(i-1))]);
// Intervalele primite ca interogari
int left, right;
while(questions--)
{
in >> left >> right;
// Lungimea intervalului cautat este right-left+1
int line = LG[(right-left+1)];
// Formez intervalul cautat ca reuniune de 2 intervale mai mici, uneori suprapuse
out << min(RMQ[line][left], RMQ[line][right-(1<<line)+1]) << '\n';
}
in.close();
out.close();
return 0;
}