Cod sursa(job #2602717)

Utilizator lev.tempfliTempfli Levente lev.tempfli Data 17 aprilie 2020 17:32:21
Problema Range minimum query Scor 30
Compilator java Status done
Runda Arhiva educationala Marime 1.88 kb


import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) throws IOException {
        File file = new File("rmq.in");
        Scanner scanner = new Scanner(file);
        FileWriter fileWriter = new FileWriter("rmq.out");
        PrintWriter printWriter = new PrintWriter(fileWriter);


        ArrayList<Integer> a = new ArrayList<>();
        int n = scanner.nextInt(), m = scanner.nextInt();
        for (int i = 0; i < n; i++)
            a.add(scanner.nextInt());

        Range_minimum_query rmq = new Range_minimum_query(a);

        for (int i = 0; i < m; i++)
            printWriter.print(rmq.query(scanner.nextInt() - 1, scanner.nextInt() - 1) + "\n");

        scanner.close();
        printWriter.close();
        fileWriter.close();
    }
}

class Range_minimum_query {
    private ArrayList<ArrayList<Integer>> lookup;

    public Range_minimum_query(ArrayList<Integer> arr) {
        lookup = new ArrayList<>();

        int lg = (int) log2(arr.size());
        for (int i = 0; i < arr.size(); i++)
            lookup.add(new ArrayList<Integer>(Collections.nCopies(lg + 1, 5)));
        for (int i = 0; i < arr.size(); i++) {
            lookup.get(i).set(0, arr.get(i));
        }
        for (int j = 1; j < lookup.get(0).size(); j++) {
            for (int i = 0; i <= lookup.size() - (1 << j); i++) {
                lookup.get(i).set(j, Math.min(lookup.get(i).get(j - 1), lookup.get(i + (1 << j) / 2).get(j - 1)));
            }
        }
    }

    public int query(int i, int j) {
        int lg = (int) log2(j - i + 1);
        return Math.min(lookup.get(i).get(lg), lookup.get(j - (1 << lg) + 1).get(lg));
    }

    private double log2(int n) {
        return (Math.log(n) / Math.log(2));
    }
}