Pagini recente » Cod sursa (job #1459694) | Cod sursa (job #1983954) | Cod sursa (job #2695317) | Cod sursa (job #3144630) | Cod sursa (job #2755612)
#include <iostream>
#include <fstream>
using namespace std;
int D[18][100010];
/**
D[i][j] = minimul dintr-o secventa de lungime 2 la i care incepe la pozitia
j in vectorul dat
practic noi precalculam minime din orice secventa posibila de lungime putere de 2
din vectorul dat
{1}
din ce aratam in continoare obtinem ca orice secventa de orice lungime
se poate compune din 2 secvente de lungime putere de 2
{1}
**/
int n, i, j, m, st, dr;
int p[18];
int lg[100010];
/// lg[i] = cel mai mare exponent al unei puteri de 2 mai mici sau egale cu i
int main ()
{
ifstream fin ("rmq.in");
ofstream fout("rmq.out");
fin>>n>>m;
for(i=1; i<=n; i++)
fin>>D[0][i];
p[0] = 1;
for (i=1; i<=18; i++)
p[i] = 2*p[i-1]; /// p[i] = 2 la puterea i
lg[1] = 0;
for (i=2; i<=n; i++)
lg[i] = 1 + lg[i/2];
for (i=1; p[i]<=n; i++)
/// calculez linia i in functie de linia i-1
for (j=1; j<=n; j++)
{
D[i][j] = D[i-1][j];
if (j+p[i-1] <= n && D[i][j] > D[i-1][ j+p[i-1] ])
D[i][j] = D[i-1][ j+p[i-1] ];
}
for (i=1; i<=m; i++)
{
fin>>st>>dr;
int e = lg[dr-st+1];
/**
L = dr-st+1;
e = 1;
while (p[e+1] <= L)
e++;
**/
/// calculez e = exeponentul celei mai mari puteri de 2
/// mai mica sau egala decat dr-st+1 (adica decat lungimea
/// intervalului dat)
/// atunci minimul din intervalul st, dr (care nu este neaparat)
/// putere de 2, il pot exprima in functie de minimul din doua
/// intervale care au lungime putere de 2 si anume:
/// - cel care incepe la pozitia st si are lungimea 2 la e
/// - cel care se termina la pozitia dr si are lungimea 2 la e
/// 2 la e fiind mai mare ca jumatate din lungimea intervaluluui
/// st, dr inseamna ca cele 2 intervale descrise mai sus se pot
/// suprapune pe undeva la mijloc dar acest lucru nu incurca
fout<<min(D[e][st], D[e][dr-p[e]+1])<<"\n";
}
return 0;
}
/**
x x x x x x x x x x
z z z z z z z z
z z z z z z z z
{1}
**/