Pagini recente » Cod sursa (job #378467) | Cod sursa (job #525858) | Cod sursa (job #826535) | Cod sursa (job #2829675) | Cod sursa (job #711784)
Cod sursa(job #711784)
#include <fstream>
#include <cstdlib>
#include <cstring>
using namespace std;
ifstream in("rmq.in");
ofstream out("rmq.out");
const int N = 100001;
const int sqrtN = 320;
int n, lim, m;
int v[N];
int am[N]; // alma mater
int pp[N]; // position in piece
int best[sqrtN][sqrtN]; // best on i-j pieces
int bTo[sqrtN][sqrtN]; // best in piece i to j
int bFrom[sqrtN][sqrtN]; // best in piece i from j
void read()
{
in >> n >> m;
for (int i = 1; i <= n; ++i)
in >> v[i];
}
inline int getSqrt(int value)
{
int i;
for (i = 1; i * i < value; ++i);
return i;
}
inline int GetMin(int a, int b)
{
return (a<b ? a:b);
}
inline int GetMin(int a, int b, int c)
{
return GetMin(a, GetMin(b, c));
}
void makeBest()
{
for (int dist = 1; dist < lim; ++dist)
for (int i = 1; i + dist < lim; ++i)
best[i][i+dist] = GetMin(best[i][i+dist-1], best[i+1][i+dist]);
}
void initialize()
{
memset(best, 0x3f3f3f3f, sizeof(best));
memset(bTo, 0x3f3f3f3f, sizeof(bTo));
memset(bFrom, 0x3f3f3f3f, sizeof(bFrom));
lim = getSqrt(n);
for (int piece = 1; piece < lim; ++piece) {
int almaMater = (piece - 1)*lim;
for (int pos = almaMater + 1; pos <= almaMater + lim && pos <= n; ++pos) {
pp[pos] = pos - almaMater;
am[pos] = piece;
bTo[piece][pp[pos]] = GetMin(bTo[piece][pp[pos]-1], v[pos]);
}
for (int pos = GetMin(almaMater + lim, n); pos > almaMater; --pos) {
bFrom[piece][pp[pos]] = GetMin(bFrom[piece][pp[pos]+1], v[pos]);
}
best[piece][piece] = bFrom[piece][1];
}
}
int getMiniAnswer(int a, int b)
{
int minim = 0x3f3f3f3f;
for (int i = a; i <= b; ++i)
if (v[i] < minim)
minim = v[i];
return minim;
}
void answerQueries()
{
while (m--) {
int a, b;
in >> a >> b;
if (am[a] == am[b]) // Sunt din aceeasi bucata
out << getMiniAnswer(a, b) << "\n";
else
out << GetMin(best[am[a] + 1][am[b] - 1], bTo[am[b]][pp[b]], bFrom[am[a]][pp[a]]) << "\n";
}
}
int main()
{
read();
initialize();
makeBest();
answerQueries();
return 0;
}