Pagini recente » Cod sursa (job #3267009) | Cod sursa (job #1688266) | Cod sursa (job #2315839) | Cod sursa (job #2482407) | Cod sursa (job #2226279)
#include <fstream>
#include <string.h>
#include <math.h>
const int INF = 1e9;
#define MAX_N 100000
#define MAX_SQ 317
#define MAX_LOG 8
int N, M;
int val[MAX_N + 1];
int lg[MAX_N + 3];
int left[MAX_N + 2];
int right[MAX_N + 2];
int rmq[MAX_LOG + 1][MAX_SQ + 1];
int shl[MAX_LOG + 1] = {1, 2, 4, 8, 16, 32, 64, 128, 256};
class Reader
{
public:
Reader() {}
Reader(const char *file_name)
{
input_file = fopen(file_name, "r");
cursor = 0;
fread(buffer, SIZE, 1, input_file);
}
inline Reader &operator >>(int &n)
{
while(buffer[cursor] < '0' || buffer[cursor] > '9')
{
advance();
}
n = 0;
while('0' <= buffer[cursor] && buffer[cursor] <= '9')
{
n = n * 10 + buffer[cursor] - '0';
advance();
}
return *this;
}
private:
FILE *input_file;
static const int SIZE = 1 << 17;
int cursor;
char buffer[SIZE];
inline void advance()
{
++ cursor;
if(cursor == SIZE)
{
cursor = 0;
fread(buffer, SIZE, 1, input_file);
}
}
};
class Writer
{
public:
Writer(const char *name):
m_stream(name)
{
memset(m_buffer, 0, sizeof(m_buffer));
m_pos = 0;
}
Writer& operator<<(int a)
{
int many = 0;
do
{
digit_buffer[many++] = a % 10 + '0';
a /= 10;
}
while (a > 0);
for (int i = many - 1; i >= 0; --i)
putchar(digit_buffer[i]);
return *this;
}
Writer& operator<<(const char *s)
{
for (; *s; ++s)
putchar(*s);
return *this;
}
~Writer()
{
m_stream.write(m_buffer, m_pos);
}
private:
void putchar(char c)
{
m_buffer[m_pos++] = c;
if (m_pos == kBufferSize)
{
m_stream.write(m_buffer, m_pos);
m_pos = 0;
}
}
static const int kBufferSize = 1 << 17;
std::ofstream m_stream;
char m_buffer[kBufferSize];
char digit_buffer[30];
int m_pos;
};
Reader f("rmq.in");
Writer g("rmq.out");
inline int MIN(const int X, const int Y) {
return X < Y ? X : Y;
}
inline int naive(int a, int b) {
int ret = INF;
while (a <= b) {
if (val[a] < ret) {
ret = val[a];
}
a++;
}
return ret;
}
inline int look(const int a, const int b) {
if (a <= b) {
return MIN(rmq[lg[b - a + 1]][a], rmq[lg[b - a + 1]][b - shl[lg[b - a + 1]] + 1]);
} else {
return INF;
}
}
int main(void) {
int i, a, b, pass = 0;
f>>N>>M;
int sq = sqrt(N);
lg[1] = 0;
for (i = 0; i < N; i++) {
f>>val[i];
if (i == pass) {
left[i] = val[i];
pass += sq;
} else {
left[i] = MIN(val[i], left[i - 1]);
}
lg[i + 2] = lg[(i + 2) >> 1] + 1;
}
pass = sq * ((N - 1) / sq);
right[N] = INF;
for (i = N - 1; i >= 0; i--) {
if (i == pass - 1) {
right[i] = val[i];
pass -= sq;
} else {
right[i] = MIN(right[i + 1], val[i]);
}
if (i == pass) {
rmq[0][pass / sq] = right[i];
}
}
int j, tmp, size = (N - 1) / sq + 1;
for (j = 1; j <= lg[size]; j++) {
tmp = size - shl[j - 1];
for (i = 0; i < tmp; i++) {
rmq[j][i] = MIN(rmq[j - 1][i], rmq[j - 1][i + shl[j - 1]]);
}
}
while (M) {
f>>a>>b;
--a; --b;
tmp = a / sq;
pass = b / sq;
if (tmp == pass) {
g<<naive(a, b)<<"\n";
} else {
g<<(MIN(left[b], MIN(right[a], look(tmp + 1, pass - 1))))<<"\n";
}
M--;
}
return 0;
}