11772. Negative Score

 

Orianna is a great swimmer and she's going to a swimming competition this month and needs your help as she is highly paranoic about the results of the competition.

The competition consists in some sort of evaluations, every judge makes a score and, based on that score and the score of other contestants she will get a score belonging to her results, those scores are final, meaning that will not change in the competition.

Orianna requires this solution with urgency, she is getting evaluated on a lot of ways and she is very worried about her results, so she wants to know what is the worst score from an evaluation A to other evaluation B inclusive.

 

Input. The first line will start with an integer t (1 ≤ t ≤ 100) representing the t test cases, then, t cases will follow, each of the cases starts with two integers n and q (1 ≤ n, q ≤ 105), denoting the number of evaluations Orianna had, then, n integers will follow denoting the score on each evaluation (from -109 to 109), after that, q queries will begin, each query consist on two integers A and B (1 ≤ A ≤ B ≤ n).

 

Output. You must output the string “Scenario #i:“, a blank line and then the result of each query, remember, Orianna is interested on the worst score from evaluation A to evaluation B inclusive.

 

Sample Input

2

5 3

1 2 3 4 5

1 5

1 3

2 4

5 3

1 -2 -4 3 -5

1 5

1 3

2 4

 

Sample Output

Scenario #1:

 

1

1

2

Scenario #2:

 

-5

-4

-4

 

 

ÐÅØÅÍÈÅ

ñòðóêòóðû äàííûõ – RMQ

 

Àíàëèç àëãîðèòìà

 çàäà÷å ñëåäóåò ðåàëèçîâàòü çàïðîñû ìèíèìóìà íà îòðåçêàõ. Ïðè ýòîì ñàì ìàññèâ ÷èñåë îñòàåòñÿ ñòàòè÷åñêèì. Ðåàëèçóåì ñòðóêòóðó äàííûõ RMQ.

 

Ðåàëèçàöèÿ àëãîðèòìà

 

#include <cstdio>

#include <cmath>

#include <vector>

#define MAX 100010

#define LOGMAX 17

 

using namespace std;

 

int mas[MAX][LOGMAX], arr[MAX];

int t, tests, n, i, q, a, b;

 

void Build_RMQ_Array(int *b)

{

  int i, j;

  for (i = 1; i <= n; i++) mas[i][0] = b[i];

  for (j = 1; (1 << j) <= n; j++)

    for (i = 1; i + (1 << j) - 1 <= n; i++)

      if (mas[i][j - 1] < mas[i + (1 << (j - 1))][j - 1])

         mas[i][j] = mas[i][j - 1];

      else mas[i][j] = mas[i + (1 << (j - 1))][j - 1];

}

 

int RMQ(int i, int j)

{

  int k = (int)(log(1.0 * j - i + 1) / log(2.0));

  int res = mas[i][k];

  if (mas[j - (1<<k) + 1][k] < res) res = mas[j - (1<<k) + 1][k];

  return res;

}

 

int main(void)

{

  scanf("%d",&tests);

  for(t = 1; t <= tests; t++)

  {

    scanf("%d %d",&n,&q);

    for(i = 1; i <= n; i++) scanf("%d",&arr[i]);

    Build_RMQ_Array(arr);

 

    printf("Scenario #%d:\n\n",t);

    for(i = 0; i < q; i++)

    {

      scanf("%d %d",&a,&b);

      printf("%d\n",RMQ(a,b));

    }

  }

  return 0;

}

 

Ðåàëèçàöèÿ ïðè ïîìîùè äåðåâà îòðåçêîâ

 

#include <cstdio>

#include <algorithm>

#define MAX 100010

#define INF 2100000000

using namespace std;

 

int SegTree[4*MAX] = {0};

int i, n, tests, t, q, a, b;

int mas[MAX];

 

void BuildTree(int *a, int v, int Left, int Right)

{

  if (Left == Right)

    SegTree[v] = a[Left];

  else

  {

    int Middle = (Left + Right) / 2;

    BuildTree(a, v*2, Left, Middle);

    BuildTree(a, v*2+1, Middle+1, Right);

    SegTree[v] = min(SegTree[v*2],SegTree[v*2+1]);

  }

}

 

int GetMin(int v, int LeftPos, int RightPos, int Left, int Right)

{

  if (Left > Right) return INF;

  if ((Left == LeftPos) && (Right == RightPos)) return SegTree[v];

 

  int Middle = (LeftPos + RightPos) / 2;

  return min(GetMin(v*2, LeftPos, Middle, Left, min(Right,Middle)),

             GetMin(v*2+1, Middle+1, RightPos, max(Left,Middle+1), Right));

}

 

int main(void)

{

  scanf("%d",&tests);

  for(t = 1; t <= tests; t++)

  {

    scanf("%d %d",&n,&q);

    for(i = 1; i <= n; i++) scanf("%d",&mas[i]);

 

    BuildTree(mas,1,1,n);

 

    printf("Scenario #%d:\n\n",t);

    for(i = 0; i < q; i++)

    {

      scanf("%d %d",&a,&b);

      printf("%d\n",GetMin(1,1,n,a,b));

    }

  }

  return 0;

}