Cod sursa(job #1741579)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 14 august 2016 14:05:41
Problema Range minimum query Scor 0
Compilator java Status done
Runda Arhiva educationala Marime 2.56 kb
import java.io.*;
import java.util.StringTokenizer;
import java.util.function.IntBinaryOperator;

public class Main {

    public static void main(String[] args) throws IOException {
        InputReader in = new InputReader(new FileInputStream("rmq.in"));

        int N = in.nextInt();
        int Q = in.nextInt();

        SparseTable table = new SparseTable(N, Math::min);

        for (int i = 0; i < N; i++) {
            table.set(i + 1, in.nextInt());
        }

        table.build();

        PrintWriter out = new PrintWriter(new FileOutputStream("rmq.out"));

        for (int i = 0; i < Q; i++) {
            int x = in.nextInt();
            int y = in.nextInt();
            out.println(table.query(x, y));
        }

        out.close();
    }

    static class SparseTable {
        private IntBinaryOperator binaryOperator;
        private int N;
        private int[][] rmq;
        private int[] log2;

        SparseTable(int N, IntBinaryOperator operator){
            this.binaryOperator = operator;
            this.N = N;
            this.rmq = new int[32 - Integer.numberOfLeadingZeros(N)][N + 1];
            this.log2 = new int[N + 1];
        }

        void set(int index, int key){
            rmq[0][index] = key;
        }

        void build(){
            log2[1] = 0;

            for (int i = 2; i <= N; i++)
                log2[i] = log2[i >> 1] + 1;

            for (int i = 1; (1 << i) <= N; ++i)
                for (int j = 1; j + (1 << i) - 1 <= N; ++j)
                    rmq[i][j] = binaryOperator.applyAsInt(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]);
        }

        int query(int x, int y){
            int k = log2[y - x + 1];
            return binaryOperator.applyAsInt(rmq[k][x], rmq[k][y - (1 << k) + 1]);
        }
    }

    static class InputReader{
        private BufferedReader reader;
        private StringTokenizer tokenizer;

        InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 65536);
            tokenizer = null;
        }

        private String nextToken() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()){
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                }
                catch (IOException e){
                    throw new RuntimeException(e);
                }
            }

            return  tokenizer.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(nextToken());
        }

        String nextString(){
            return nextToken();
        }
    }
}