Permutasiya#4079

Permutasiya (Həll təhlili)

massivi orijinal permutasiyanı saxlasın. massivini aşağıdakı kimi qurun:

a[x] = x~ədədinin~b~massivindəki~mövqeyi

Məsələn, əgər

olarsa, onda

sorğusunun cavabı a[RMQa[u..v]]-dir.

Nümunə

massivi ilə verilmiş giriş permutasiyasını nəzərdən keçirək və ona əsasən köməkçi massivini quruq.

Məsələn, ədədi permutasiyada -cu mövqedədir (yəni b[9] = 1). Buna görə a[1] = 9 qoyuruq.

İndi (a, b) = (2, 4) sorğusunu nəzərdən keçirək. ədədi -cü mövqedədir, ədədi -cu mövqedədir, ədədi isə -ci mövqedədir. Beləliklə, massivində və indeksli elementlər müvafiq olaraq və -yə bərabərdir — bunlar və ədədlərinin orijinal massivindəki mövqeləridir.

alt massivindəki minimum dəyəri tapmaq qalır. O, -ə bərabərdir ( və arasındakı minimum). Buna görə cavab -cü mövqedir.

Alqoritmin implementasiyası

massivini elan edin, burada mas[i][j] (i, ..., i + 2^j - 1) seqmentindəki minimum elementin indeksini saxlayacaq. Köməkçi və massivlərini elan edin.

#define DIM1 100010
#define DIM2 17
int mas[DIM1][DIM2];
int a[DIM1], b[DIM1];

Build_RMQ_Array funksiyası massivinə əsasən massivini elə qurur ki,

mas[i][j] = min(b_i, b_{i+1}, ..., b_{i+2^j})
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++)
      mas[i][j] = min(mas[i][j - 1], mas[i + (1 << (j - 1))][j - 1]);
}

RMQ funksiyası (b_i, b_{i+1}, ..., b_j) seqmentindəki minimum dəyəri vaxtda qaytarır.

int RMQ(int i, int j)
{
  int k = 0;
  while ((1 << (k + 1)) <= j - i + 1) k++; 
  return min(mas[i][k],mas[j - (1<<k) + 1][k]);
}

Giriş məlumatlarını oxuyun və permutasiyanı massivində saxlayın.

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

massivini qurun.

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

sorğularını dəstəkləmək üçün ilkin emal aparın.

Build_RMQ_Array(a);

Hər sorğusu üçün cavabı hesablayın və çap edin.

for (i = 0; i < q; i++)
{
  scanf("%d %d",&u,&v);
  printf("%d\n",RMQ(u,v));
}

Java implementasiyası

import java.util.*;

public class Main
{
  private final static int DIM1 = 100010;
  private final static int DIM2 = 17;
  static int[] a = new int[DIM1];    
  static int[] b = new int[DIM1];    
  static int[][] mas = new int[DIM1][DIM2];
  
  static int min(int a, int b)
  {
    return (a < b) ? a : b;
  }
  
  static void Build_RMQ_Array(int[] b, int n)
  {
    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++)
        mas[i][j] = 
          min(mas[i][j - 1], mas[i + (1 << (j - 1))][j - 1]);
  }

  static int RMQ(int i, int j)
  {
    int k = 0;
    while ((1 << (k + 1)) <= j - i + 1) k++; 
    return min(mas[i][k],mas[j - (1<<k) + 1][k]);
  }
  
  public static void main(String[] args)
  {
    Scanner con = new Scanner(System.in);
    int i, n = con.nextInt(), 
           q = con.nextInt();
    for (i = 1; i <= n; i++) b[i] = con.nextInt();
    for (i = 1; i <= n; i++) a[b[i]] = i;
    
    Build_RMQ_Array(a, n);

    for(i = 0; i < q; i++)
    {
      int u = con.nextInt();
      int v = con.nextInt();
      System.out.println(RMQ(u,v));
    }
  }
}