Pagini recente » Cod sursa (job #3291777) | Cod sursa (job #721106) | Cod sursa (job #617985) | Cod sursa (job #2644925) | Cod sursa (job #2069651)
#include<iostream>
#include<fstream>
#include<cassert>
#include<cmath>
using namespace std;
ifstream in("rmq.in");
ofstream out("rmq.out");
const int N = 100000;
const int NLOG = 17 + 1; /// +1 Because we want to include level 0 too!
void array_to_RMQ_matrix(int v[], int n, int rmq[][N], int MAX_LEVEL){ /// Creates min() RMQ table "rmq" from Array "v"
/// Compute RMQ level 0
for(int i=0; i<n; ++i)
rmq[0][i] = v[i];
//for(int index = 0; index < n; ++index) cout<<rmq[0][index]<<" "; cout<<"\n";
/// Compute RMQ levels 1 to MAX_LEVEL
for(int level = 1; level <= 17; ++level)
{
int sequence_length = 1 << level;
int last_sequence_index = n - sequence_length + 1;
for(int index = 0; index < last_sequence_index; ++index)
rmq[level][index] = min(rmq[level-1][index], rmq[level-1][index + sequence_length / 2]);
//for(int index = 0; index < last_sequence_index; ++index) cout<<rmq[level][index]<<" "; cout<<"\n";
}
}
int MSD(int x){ /// Base 2 MSD of number X
while(x & (x-1)) /// X isn't a power of 2 yet
x &= x-1; /// Remove X's LSD
return x;
}
int queryRMQ(int rmq[][N], int n, int a, int b){ /// Queries the RMQ table in interval [a, b]
int query_interval_length = b-a+1;
int sequence_length = MSD(query_interval_length); /// The maximal RMQ sequence length we can query
int level = log2(sequence_length);
int offset = query_interval_length - sequence_length;
return min(rmq[level][a], rmq[level][a + offset]); /// min <- [a, a + 2^level] U [a+offset, b]
}
int main()
{
/// Local Variables
int rmqArray[NLOG][N]; /// rmqArray[level][index] = min(index, index+1, ..., index + 2^level);
int values[N];
int n,q;
/// Unit Testing :D
assert(MSD(16) == 16); /// 10000
assert(MSD(9) == 8); /// 01001
assert(MSD(7) == 4); /// 00111
/// Input
in>>n>>q;
for(int i=0; i<n; ++i)
in>>values[i];
/// Compute RMQ table
array_to_RMQ_matrix(values, n, rmqArray, NLOG);
/// Answer the queries
for(int i=0; i<q; ++i)
{
int leftBound, rightBound;
in>>leftBound>>rightBound;
out<<queryRMQ(rmqArray, n, leftBound-1, rightBound-1)<<"\n";
}
return 0;
}